diff -Nuar gdb-5.1.1.orig/gdb/acconfig.h gdb-5.1.1/gdb/acconfig.h
--- gdb-5.1.1.orig/gdb/acconfig.h	Sat Mar 31 22:09:02 2001
+++ gdb-5.1.1/gdb/acconfig.h	Fri May 24 04:16:20 2002
@@ -170,3 +170,10 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* define to have target attach feature */
+#undef HAVE_TARGET_ATTACH
+
+/* define to have target remote shell feature */
+#undef HAVE_TARGET_SHELL
+
diff -Nuar gdb-5.1.1.orig/gdb/config/powerpc/tm-linux.h gdb-5.1.1/gdb/config/powerpc/tm-linux.h
--- gdb-5.1.1.orig/gdb/config/powerpc/tm-linux.h	Tue Mar 20 21:16:20 2001
+++ gdb-5.1.1/gdb/config/powerpc/tm-linux.h	Fri May 24 04:16:20 2002
@@ -66,4 +66,28 @@
    to be relocated. */
 #define SOFUN_ADDRESS_MAYBE_MISSING
 
+#ifdef HAVE_TARGET_ATTACH
+#define GDB_TARGET_POWERPC
+#define NPC_REGNUM (-1)
+#define FP_REGNUM 1		/* Contains address of executing stack frame */
+#define SP_REGNUM 1		/* Contains address of top of stack */
+#define PC_REGNUM 64		/* Program counter (instruction address %iar) */
+#define PS_REGNUM 65		/* Processor (or machine) status (%msr) */
+#define	CR_REGNUM 66		/* Condition register */
+#define	LR_REGNUM 67		/* Link register */
+#define	CTR_REGNUM 68		/* Count register */
+#define	XER_REGNUM 69		/* Fixed point exception registers */
+#define	MQ_REGNUM 70		/* Multiply/quotient register */
+#define REGISTER_BYTES 880
+#define FP0_REGNUM 32		/* FPR (Floating point) register 0 */
+#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 32 ? 8 : 4)
+#define REGISTER_BYTE(N)  \
+ (								\
+  ((N) > FPLAST_REGNUM) ? ((((N) - FPLAST_REGNUM -1) * 4) + 384)\
+  :((N) >= FP0_REGNUM) ? ((((N) - FP0_REGNUM) * 8) + 128)	\
+  :((N) * 4) )
+#define KERNEL_U_ADDR 0x0
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+        (addr) = ppc_register_u_addr ((blockend),(regno));
+#endif
 #endif  /* #ifndef TM_LINUX_H */
diff -Nuar gdb-5.1.1.orig/gdb/config.in gdb-5.1.1/gdb/config.in
--- gdb-5.1.1.orig/gdb/config.in	Mon Jul 23 23:21:51 2001
+++ gdb-5.1.1/gdb/config.in	Fri May 24 04:16:20 2002
@@ -160,6 +160,12 @@
 /* Define if <sys/ptrace.h> defines the PTRACE_GETFPXREGS request.  */
 #undef HAVE_PTRACE_GETFPXREGS
 
+/* define to have target attach feature */
+#undef HAVE_TARGET_ATTACH
+
+/* define to have target remote shell feature */
+#undef HAVE_TARGET_SHELL
+
 /* Define if <sys/ptrace.h> defines the PT_GETDBREGS request.  */
 #undef HAVE_PT_GETDBREGS
 
diff -Nuar gdb-5.1.1.orig/gdb/configure.in gdb-5.1.1/gdb/configure.in
--- gdb-5.1.1.orig/gdb/configure.in	Fri Aug  3 01:30:22 2001
+++ gdb-5.1.1/gdb/configure.in	Fri May 24 04:16:20 2002
@@ -50,6 +50,8 @@
 CONFIG_CLEAN=
 CONFIG_INSTALL=
 CONFIG_UNINSTALL=
+AC_DEFINE(HAVE_TARGET_ATTACH)
+AC_DEFINE(HAVE_TARGET_SHELL)
 
 configdirs="doc testsuite"
 
diff -Nuar gdb-5.1.1.orig/gdb/configure gdb-5.1.1/gdb/configure
--- gdb-5.1.1.orig/gdb/configure	Fri Aug  3 01:30:20 2001
+++ gdb-5.1.1/gdb/configure	Fri May 24 04:16:20 2002
@@ -2812,6 +2825,14 @@
 CONFIG_CLEAN=
 CONFIG_INSTALL=
 CONFIG_UNINSTALL=
+cat >> confdefs.h <<\EOF
+#define HAVE_TARGET_ATTACH 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define HAVE_TARGET_SHELL 1
+EOF
+
 
 configdirs="doc testsuite"
 
diff -pur --exclude='*.o' gdb-5.2.1-orig/gdb/blockframe.c gdb-5.2.1/gdb/blockframe.c
--- gdb-5.2.1-orig/gdb/blockframe.c	Wed Feb 27 21:04:29 2002
+++ gdb-5.2.1/gdb/blockframe.c	Wed Sep 10 15:54:37 2003
@@ -264,7 +264,11 @@ reinit_frame_cache (void)
   flush_cached_frames ();
 
   /* FIXME: The inferior_ptid test is wrong if there is a corefile.  */
+#ifdef HAVE_TARGET_ATTACH
+  if (PIDGET (inferior_ptid) != 0 && PIDGET (inferior_ptid) != -1)
+#else  
   if (PIDGET (inferior_ptid) != 0)
+#endif  
     {
       select_frame (get_current_frame (), 0);
     }
diff -pur --exclude='*.o' gdb-5.2.1-orig/gdb/exec.c gdb-5.2.1/gdb/exec.c
--- gdb-5.2.1-orig/gdb/exec.c	Wed Jan  9 19:49:22 2002
+++ gdb-5.2.1/gdb/exec.c	Wed Sep 10 15:54:37 2003
@@ -773,3 +773,21 @@ exec_make_note_section (bfd *obfd, int *
 {
   error ("Can't create a corefile");
 }
+#ifdef HAVE_TARGET_SHELL
+static void
+rshell_command(char *arg, int from_tty)
+{
+  while (arg && isspace(*arg))
+	arg++;
+  if (arg && *arg && current_target.to_exec_shellcmd)
+    (*current_target.to_exec_shellcmd) (arg, from_tty);
+}
+
+void
+_initialize_rshell_commands()
+{
+  add_com ("rshell", class_vars, rshell_command,
+	"execute remote shell command");
+  add_com_alias ("rsh", "rshell", class_vars, 1);
+}
+#endif
diff -pur --exclude='*.o' gdb-5.2.1-orig/gdb/infcmd.c gdb-5.2.1/gdb/infcmd.c
--- gdb-5.2.1-orig/gdb/infcmd.c	Wed Feb  6 14:00:45 2002
+++ gdb-5.2.1/gdb/infcmd.c	Wed Sep 10 15:54:37 2003
@@ -1729,7 +1729,11 @@ attach_command (char *args, int from_tty
 
   dont_repeat ();		/* Not for the faint of heart */
 
+#ifdef HAVE_TARGET_ATTACH
+  if (target_has_execution && !ptid_equal(inferior_ptid,null_ptid))
+#else  
   if (target_has_execution)
+#endif	  
     {
       if (query ("A program is being debugged already.  Kill it? "))
 	target_kill ();
diff -pur --exclude='*.o' gdb-5.2.1-orig/gdb/remote.c gdb-5.2.1/gdb/remote.c
--- gdb-5.2.1-orig/gdb/remote.c	Wed Feb 27 02:18:39 2002
+++ gdb-5.2.1/gdb/remote.c	Wed Sep 10 16:30:36 2003
@@ -128,6 +128,9 @@ static void remote_async_kill (void);
 
 static int tohex (int nib);
 
+#ifdef HAVE_TARGET_ATTACH
+static void remote_attach PARAMS ((char *args, int from_tty));
+#endif 
 static void remote_detach (char *args, int from_tty);
 static void remote_async_detach (char *args, int from_tty);
 
@@ -1033,6 +1036,12 @@ set_thread (int th, int gen)
     sprintf (&buf[2], "%x", th);
   putpkt (buf);
   getpkt (buf, (rs->remote_packet_size), 0);
+#ifdef HAVE_TARGET_ATTACH
+  if (buf[0] == 'E')
+    {
+      error ("Remote failure reply: %s", buf);
+    }
+#endif
   if (gen)
     general_thread = th;
   else
@@ -2116,6 +2125,10 @@ remote_start_remote_dummy (void *dummy)
 static int
 remote_start_remote (PTR dummy)
 {
+#ifdef HAVE_TARGET_ATTACH
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+#endif
   immediate_quit++;		/* Allow user to interrupt it */
 
   /* Ack any packet which the remote side has already sent.  */
@@ -2129,6 +2142,20 @@ remote_start_remote (PTR dummy)
   get_offsets ();		/* Get text, data & bss offsets */
 
   putpkt ("?");			/* initiate a query from remote machine */
+#ifdef HAVE_TARGET_ATTACH
+  getpkt(buf, (rs->remote_packet_size), 0);
+  if (buf[0] == 'E')
+    {
+      error ("Remote failure reply: %s", buf);
+    } else
+ if (buf[0] == 'I')
+    {
+      inferior_ptid = null_ptid;
+      return 1;			/* Remote server is idle waiting for attach */
+    }
+  putpkt ("?");			/* wait_for_inferior() called in start_remote
+				   expects "wait status" packet */
+#endif
   immediate_quit--;
 
   return remote_start_remote_dummy (dummy);
@@ -2239,6 +2266,9 @@ remote_open_1 (char *name, int from_tty,
 
   unpush_target (target);
 
+#ifdef HAVE_TARGET_ATTACH
+ reread_symbols();
+#endif 
   remote_desc = serial_open (name);
   if (!remote_desc)
     perror_with_name (name);
@@ -2314,7 +2344,11 @@ remote_open_1 (char *name, int from_tty,
      support svr4 shared libraries.  */
 
   /* Set up to detect and load shared libraries. */
+#ifdef HAVE_TARGET_ATTACH
+  if (exec_bfd && !ptid_equal(inferior_ptid ,null_ptid) )
+#else  
   if (exec_bfd) 	/* No use without an exec file. */
+#endif	  
     {
       SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
       remote_check_symbols (symfile_objfile);
@@ -2337,6 +2371,9 @@ remote_async_open_1 (char *name, int fro
 
   unpush_target (target);
 
+#ifdef HAVE_TARGET_ATTACH
+ reread_symbols();
+#endif 
   remote_desc = serial_open (name);
   if (!remote_desc)
     perror_with_name (name);
@@ -2436,6 +2473,59 @@ remote_async_open_1 (char *name, int fro
 #endif
 }
 
+#ifdef HAVE_TARGET_SHELL
+static void (*ofunc)();
+static void
+remote_exec_shellcmd(char *arg, int from_tty)
+{
+  int len, ch;
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+
+  sprintf(buf, "E%*s", (int)(rs->remote_packet_size - 2), arg);
+  putpkt(buf);
+
+  ofunc = (void (*)()) signal (SIGINT, remote_interrupt);
+  while ((len = readchar(-1)) > 0)
+    {
+      while (len-- > 0)
+	{
+	  if ((ch = readchar(-1)) < 0)
+	    return;
+	  fputc_unfiltered(ch, gdb_stderr);
+	}
+    }
+  gdb_flush(gdb_stderr);
+  signal (SIGINT, ofunc);
+}
+#endif
+#ifdef HAVE_TARGET_ATTACH
+static void
+remote_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+  char *p;
+  int pid, i;
+
+  if ((pid = atoi(args)) <= 0)
+     error ("Bogus pid.");
+  if (!(p = (char *) get_exec_file (0), pid))
+    error ("No executable file.\nUse the \"file\" or \"exec-file\" command.");
+
+  if (from_tty)
+    {
+      printf_unfiltered ("Attaching to remote program `%s' (process %d)...\n",
+			p, pid);
+      gdb_flush (gdb_stdout);
+    }
+  sprintf(buf, "U%02x", pid);
+  putpkt (buf);
+}
+
+#endif
 /* This takes a program previously attached to and detaches it.  After
    this is done, GDB can be used to debug some other program.  We
    better not have left any breakpoints in the target program or it'll
@@ -2447,6 +2537,14 @@ remote_detach (char *args, int from_tty)
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size);
 
+#ifdef HAVE_TARGET_ATTACH  
+  if (args)
+    sprintf(buf, "D%02x", atoi(args));
+  else
+    sprintf(buf, "D");
+  putpkt (buf);
+  target_mourn_inferior();
+#else
   if (args)
     error ("Argument given to \"detach\" when remotely debugging.");
 
@@ -2455,6 +2553,7 @@ remote_detach (char *args, int from_tty)
   remote_send (buf, (rs->remote_packet_size));
 
   target_mourn_inferior ();
+#endif  
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
 
@@ -2979,7 +3078,11 @@ remote_wait (ptid_t ptid, struct target_
       switch (buf[0])
 	{
 	case 'E':		/* Error of some sort */
+#ifdef HAVE_TARGET_ATTACH
+          error ("Remote failure reply: %s", buf);		
+#else			
 	  warning ("Remote failure reply: %s", buf);
+#endif	  
 	  continue;
 	case 'T':		/* Status with PC, SP, FP, ... */
 	  {
@@ -3047,6 +3150,11 @@ Packet: '%s'\n",
 		  }
 	      }
 	  }
+#ifdef HAVE_TARGET_ATTACH
+	/* Register values are meaningful only after user code has started. */
+	  if (ptid_equal(inferior_ptid ,null_ptid))
+	    registers_changed();	/* invalidate all registers */
+#endif
 	  /* fall through */
 	case 'S':		/* Old style status, just signal only */
 	  status->kind = TARGET_WAITKIND_STOPPED;
@@ -3133,6 +3241,13 @@ Packet Dropped");
 	  kill_kludge = 1;
 
 	  goto got_status;
+#ifdef HAVE_TARGET_ATTACH
+	case 'I':
+	 inferior_ptid=null_ptid;
+	 registers_changed();
+	 goto got_status;
+
+#endif
 	case 'O':		/* Console output */
 	  remote_console_output (buf + 1);
 	  continue;
@@ -4528,6 +4643,15 @@ extended_remote_mourn (void)
 #if 0
   remote_mourn_1 (&extended_remote_ops);
 #endif
+#ifdef HAVE_TARGET_ATTACH
+  /* CAUTION: The following call dependently assumes that
+     reopen_exec_file() called in generic_mourn_inferior() is
+     an empty function. Should it does something regarding
+     a real executable file, the extended-remote target could
+     be hurt.
+   */
+  generic_mourn_inferior ();	/* But we do need to clean up */
+#endif
 }
 
 /* Worker function for remote_mourn.  */
@@ -4554,6 +4678,10 @@ extended_remote_create_inferior (char *e
 
   /* Now restart the remote server.  */
   extended_remote_restart ();
+#ifdef HAVE_TARGET_ATTACH
+  if (!target_has_execution)
+    return;	/* Maybe idle waiting for attach command */
+#endif
 
   /* Now put the breakpoints back in.  This way we're safe if the
      restart function works via a unix fork on the remote side.  */
@@ -5356,6 +5484,12 @@ Specify the serial device it is connecte
 (e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).";
   remote_ops.to_open = remote_open;
   remote_ops.to_close = remote_close;
+#ifdef HAVE_TARGET_ATTACH
+  remote_ops.to_attach = remote_attach;
+#endif
+#ifdef HAVE_TARGET_SHELL
+  remote_ops.to_exec_shellcmd = remote_exec_shellcmd;
+#endif
   remote_ops.to_detach = remote_detach;
   remote_ops.to_resume = remote_resume;
   remote_ops.to_wait = remote_wait;
diff -pur --exclude='*.o' gdb-5.2.1-orig/gdb/target.c gdb-5.2.1/gdb/target.c
--- gdb-5.2.1-orig/gdb/target.c	Fri Feb  1 02:01:21 2002
+++ gdb-5.2.1/gdb/target.c	Wed Sep 10 15:54:37 2003
@@ -540,6 +540,9 @@ update_current_target (void)
       INHERIT (to_open, t);
       INHERIT (to_close, t);
       INHERIT (to_attach, t);
+#ifdef HAVE_TARGET_SHELL
+      INHERIT (to_exec_shellcmd, t);
+#endif
       INHERIT (to_post_attach, t);
       INHERIT (to_require_attach, t);
       INHERIT (to_detach, t);
@@ -1398,7 +1401,11 @@ generic_mourn_inferior (void)
 {
   extern int show_breakpoint_hit_counts;
 
+#ifdef HAVE_TARGET_ATTACH
+ inferior_ptid = pid_to_ptid (-1);
+#else  
   inferior_ptid = null_ptid;
+#endif  
   attach_flag = 0;
   breakpoint_init_inferior (inf_exited);
   registers_changed ();
diff -pur --exclude='*.o' gdb-5.2.1-orig/gdb/target.h gdb-5.2.1/gdb/target.h
--- gdb-5.2.1-orig/gdb/target.h	Sun Feb 10 05:08:42 2002
+++ gdb-5.2.1/gdb/target.h	Wed Sep 10 15:54:37 2003
@@ -320,6 +320,9 @@ struct target_ops
 				   void *);
     char * (*to_make_corefile_notes) (bfd *, int *);
     int to_magic;
+#ifdef HAVE_TARGET_SHELL
+  void        (*to_exec_shellcmd) PARAMS ((char *, int));
+#endif
     /* Need sub-structure for target machine related rather than comm related?
      */
   };
