diff --git a/arm.c b/arm.c
index 1065c9d..26d4f61 100644
--- a/arm.c
+++ b/arm.c
@@ -1099,6 +1099,115 @@ arm_get_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
 	return TRUE;
 }
 
+
+int gdb_get_register(int regno, char *buf)
+{
+	const struct machine_specific *ms = machdep->machspec;
+	struct task_context *tc;
+	const char *cpu_context;
+	ulong offset = 0;
+	ulong val;
+	int i;
+
+// 	fprintf(fp, "%s regno %d\n", __func__, regno);
+
+	tc = CURRENT_CONTEXT();
+
+       if (ms->crash_task_regs && is_task_active(tc->task)) {
+               struct arm_pt_regs *regs = &ms->crash_task_regs[tc->processor];
+
+               switch (regno) {
+               case 0 ... 15:
+                       val = regs->uregs[regno];
+                       break;
+
+               default:
+                       return FALSE;
+               }
+
+               memcpy(buf, &val, 4);
+               return TRUE;
+       }
+
+	if (!fill_thread_info(tc->thread_info))
+		return FALSE;
+
+	cpu_context = tt->thread_info + OFFSET(thread_info_cpu_context);
+
+#if 0
+struct cpu_context_save {
+   [0] __u32 r4;
+   [4] __u32 r5;
+   [8] __u32 r6;
+  [12] __u32 r7;
+  [16] __u32 r8;
+  [20] __u32 r9;
+  [24] __u32 sl;
+  [28] __u32 fp;
+  [32] __u32 sp;
+  [36] __u32 pc;
+  [40] __u32 extra[2];
+}
+#endif
+
+	switch (regno) {
+	case 4 ... 11:
+		offset = 4 * (regno - 4);
+		break;
+
+	case 13:
+		offset = 32;
+		break;
+
+	case 15:
+		offset = 36;
+		break;
+
+	default:
+		return FALSE;
+	}
+
+	val = *((ulong *)(cpu_context + offset));
+	memcpy(buf, &val, 4);
+
+	return TRUE;
+}
+
+static void setreg(const char *cpu_context, ulong offset, int regnum)
+{
+	char buf[100];
+	ulong val;
+
+	val = *((ulong *)(cpu_context + offset));
+	snprintf(buf, sizeof(buf), "set $r%d = %#x\n", regnum, val);
+
+	fprintf(fp, "%s\n", buf);
+
+	gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR);
+}
+void cmd_gdbset(void)
+{
+	struct task_context *tc;
+	const char *cpu_context;
+	ulong offset = 0;
+	int i;
+
+	tc = CURRENT_CONTEXT();
+
+	if (!fill_thread_info(tc->thread_info))
+		return;
+
+	cpu_context = tt->thread_info + OFFSET(thread_info_cpu_context);
+
+	for (i = 4; i <= 11; i++) {
+		setreg(cpu_context, offset, i);
+		offset += 4;
+	}
+
+	setreg(cpu_context, offset, 13);
+	setreg(cpu_context, offset + 4, 15);
+}
+
 /*
  * Get the starting point for the active cpu in a diskdump.
  */
diff --git a/defs.h b/defs.h
index 77a623d..2d536f5 100755
--- a/defs.h
+++ b/defs.h
@@ -3674,6 +3674,7 @@ void cmd_foreach(void);      /* task.c */
 void cmd_runq(void);         /* task.c */
 void cmd_sig(void);          /* task.c */
 void cmd_bt(void);           /* kernel.c */
+void cmd_gdbset(void);           /* kernel.c */
 void cmd_dis(void);          /* kernel.c */
 void cmd_mod(void);          /* kernel.c */
 void cmd_log(void);          /* kernel.c */
diff --git a/gdb-7.3.1.patch b/gdb-7.3.1.patch
index 4e1c08b..2cf3821 100644
--- a/gdb-7.3.1.patch
+++ b/gdb-7.3.1.patch
@@ -1357,3 +1357,146 @@
  	      if (!field_is_static (&TYPE_FIELD (type, i))
  		  && TYPE_FIELD_PACKED (type, i))
  		{
+--- gdb-7.3.1/gdb/arm-linux-tdep.c.orig	2012-03-13 19:41:55.009207631 +0530
++++ gdb-7.3.1/gdb/arm-linux-tdep.c	2012-03-13 19:46:51.845202848 +0530
+@@ -1025,18 +1025,18 @@
+   set_gdbarch_fetch_tls_load_module_address (gdbarch,
+                                              svr4_fetch_objfile_link_map);
+ 
+-  tramp_frame_prepend_unwinder (gdbarch,
+-				&arm_linux_sigreturn_tramp_frame);
+-  tramp_frame_prepend_unwinder (gdbarch,
+-				&arm_linux_rt_sigreturn_tramp_frame);
+-  tramp_frame_prepend_unwinder (gdbarch,
+-				&arm_eabi_linux_sigreturn_tramp_frame);
+-  tramp_frame_prepend_unwinder (gdbarch,
+-				&arm_eabi_linux_rt_sigreturn_tramp_frame);
+-  tramp_frame_prepend_unwinder (gdbarch,
+-				&arm_linux_restart_syscall_tramp_frame);
+-  tramp_frame_prepend_unwinder (gdbarch,
+-				&arm_kernel_linux_restart_syscall_tramp_frame);
++//   tramp_frame_prepend_unwinder (gdbarch,
++// 				&arm_linux_sigreturn_tramp_frame);
++//   tramp_frame_prepend_unwinder (gdbarch,
++// 				&arm_linux_rt_sigreturn_tramp_frame);
++//   tramp_frame_prepend_unwinder (gdbarch,
++// 				&arm_eabi_linux_sigreturn_tramp_frame);
++//   tramp_frame_prepend_unwinder (gdbarch,
++// 				&arm_eabi_linux_rt_sigreturn_tramp_frame);
++//   tramp_frame_prepend_unwinder (gdbarch,
++// 				&arm_linux_restart_syscall_tramp_frame);
++//   tramp_frame_prepend_unwinder (gdbarch,
++// 				&arm_kernel_linux_restart_syscall_tramp_frame);
+ 
+   /* Core file support.  */
+   set_gdbarch_regset_from_core_section (gdbarch,
+--- gdb-7.3.1/gdb/target.c.orig	2012-03-13 19:41:56.517207609 +0530
++++ gdb-7.3.1/gdb/target.c	2012-03-13 19:46:55.821202785 +0530
+@@ -1672,6 +1672,26 @@
+    deal with partial reads should call target_read (which will retry until
+    it makes no progress, and then return how much was transferred).  */
+ 
++#ifdef CRASH_MERGE
++#define CORELOW_PID 1
++
++int gdb_context_changed(void)
++{
++  static int done;
++
++  if (!done)
++   {
++     done = 1;	
++
++     inferior_appeared (current_inferior (), CORELOW_PID);
++     inferior_ptid = pid_to_ptid (CORELOW_PID);
++     add_thread_silent (inferior_ptid);
++   }
++
++   registers_changed ();
++}
++#endif
++
+ int
+ target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+ {
+@@ -1698,6 +1718,13 @@
+ int
+ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+ {
++#ifdef CRASH_MERGE
++  extern int gdb_readmem_callback(unsigned long, void *, int, int);
++  if (gdb_readmem_callback(memaddr, (void *)myaddr, len, 0))
++        return 0;
++  else
++	return EIO;
++#endif
+   /* Dispatch to the topmost target, not the flattened current_target.
+      Memory accesses check target->to_has_(all_)memory, and the
+      flattened target doesn't inherit those.  */
+@@ -3206,9 +3233,44 @@
+ /* Set up the handful of non-empty slots needed by the dummy target
+    vector.  */
+ 
++#include "frame.h"		/* required by inferior.h */
++#include "inferior.h"
++
++#include "regcache.h"
++
++static unsigned int regs[40];
++
++static void
++get_core_registers (struct target_ops *ops,
++		    struct regcache *regcache, int regno)
++{
++  int i;
++
++  /* Mark all registers not found in the core as unavailable.  */
++  for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
++    if (regcache_register_status (regcache, i) == REG_UNKNOWN) {
++      extern int gdb_get_register(int regno, char *buf);
++      char buf[32];
++      int ret = gdb_get_register(i, buf);
++      // int ret = 0;
++
++      regcache_raw_supply (regcache, i, ret ? buf : NULL);
++    }
++}
++
++#define CORELOW_PID 1
++
++static void
++core_open (char *filename, int from_tty)
++{
++	printf("WIN WIN WIN\n");
++	exit(1);
++}
++
+ static void
+ init_dummy_target (void)
+ {
++	dummy_target.to_open =  core_open;
+   dummy_target.to_shortname = "None";
+   dummy_target.to_longname = "None";
+   dummy_target.to_doc = "";
+@@ -3228,16 +3290,18 @@
+   dummy_target.to_xfer_partial = default_xfer_partial;
+   dummy_target.to_has_all_memory = (int (*) (struct target_ops *)) return_zero;
+   dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero;
+-  dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero;
+-  dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero;
++  dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_one;
++  dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_one;
+   dummy_target.to_has_execution
+     = (int (*) (struct target_ops *, ptid_t)) return_zero;
+   dummy_target.to_stopped_by_watchpoint = return_zero;
+   dummy_target.to_stopped_data_address =
+     (int (*) (struct target_ops *, CORE_ADDR *)) return_zero;
+   dummy_target.to_magic = OPS_MAGIC;
++
++  dummy_target.to_fetch_registers = get_core_registers;
+ }
+-
++
+ static void
+ debug_to_open (char *args, int from_tty)
+ {
diff --git a/gdb_interface.c b/gdb_interface.c
index 1612df1..97c2fdd 100755
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -678,8 +678,8 @@ static char *prohibited_list[] = {
 	"run", "r", "break", "b", "tbreak", "hbreak", "thbreak", "rbreak",
 	"watch", "rwatch", "awatch", "attach", "continue", "c", "fg", "detach", 
 	"finish", "handle", "interrupt", "jump", "kill", "next", "nexti", 
-	"signal", "step", "s", "stepi", "target", "thread", "until", "delete", 
-	"clear", "disable", "enable", "condition", "ignore", "frame", 
+	"signal", "step", "s", "stepi", "trget", "thread", "until", "delete", 
+	"clear", "disable", "enable", "condition", "ignore", "framed", 
 	"select-frame", "f", "up", "down", "catch", "tcatch", "return",
 	"file", "exec-file", "core-file", "symbol-file", "load", "si", "ni", 
 	"shell", 
@@ -816,7 +816,7 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
 			memtype = UVADDR;
 		} else {
 			if (CRASHDEBUG(1))
-			        console("gdb_readmem_callback: %lx %d FAILED\n",
+			        fprintf(fp, "gdb_readmem_callback: %lx %d FAILED\n",
 					addr, len);
 			return FALSE;
 		}
@@ -824,7 +824,7 @@ gdb_readmem_callback(ulong addr, void *buf, int len, int write)
 		memtype = KVADDR;
 
 	if (CRASHDEBUG(1))
-		console("gdb_readmem_callback[%d]: %lx %d\n", 
+		fprintf(fp, "gdb_readmem_callback[%d]: %lx %d\n", 
 			memtype, addr, len);
 
 	if (memtype == FILEADDR)
diff --git a/global_data.c b/global_data.c
index 98a5a79..81cdee0 100755
--- a/global_data.c
+++ b/global_data.c
@@ -118,6 +118,7 @@ struct command_table_entry linux_command_table[] = {
 	{"waitq",   cmd_waitq,   help_waitq,   REFRESH_TASK_TABLE},
 	{"whatis",  cmd_whatis,  help_whatis,  0},
 	{"wr",      cmd_wr,      help_wr,      0},
+        {"gdbset",      cmd_gdbset,      help_bt,      0},
 #if defined(S390) || defined(S390X)
         {"s390dbf", cmd_s390dbf, help_s390dbf, 0},
 #endif
diff --git a/task.c b/task.c
index 002e8b6..d65216c 100755
--- a/task.c
+++ b/task.c
@@ -4121,6 +4121,8 @@ comm_exists(char *s)
         return cnt;
 }
 
+// extern void arm_set_context(struct task_context *tc);
+
 /*
  *  Set a new context.  If only a pid is passed, the first task found with
  *  that pid is selected.
@@ -4145,7 +4147,10 @@ set_context(ulong task, ulong pid)
         }
 
 	if (found) {
+		extern void gdb_context_changed();
+
 		CURRENT_CONTEXT() = tc;
+		gdb_context_changed();
 		return TRUE;
 	} else {
 		if (task) 
