2005-06-03  Michael Snyder  <msnyder@redhat.com>

	* tracepoint.c, remote.c, target.c, target.h, etc.:
	Begin moving tracepoint methods into the target vector,
	and migrating some of the remote protocol stuff from
	tracepoint.c into remote.c.
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 922b105..ec29314 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,11 @@
-2005-05-12  Michael Snyder  <msnyder@redhat.com>
+2005-06-03  Michael Snyder  <msnyder@redhat.com>
+
+	* tracepoint.c, remote.c, target.c, target.h, etc.: 
+	Begin moving tracepoint methods into the target vector,
+	and migrating some of the remote protocol stuff from
+	tracepoint.c into remote.c.
+
+2005-06-03  Michael Snyder  <msnyder@redhat.com>
 
 	* tracepoint.c (emit_checkpoint_method4): Add PC to ckpt record.
 	* target.c (target_read_memory_trusted): New function.
diff --git a/gdb/remote.c b/gdb/remote.c
index f1d4a69..fdf4e7d 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -58,6 +58,8 @@
 
 #include "remote-fileio.h"
 
+#include "tracepoint.h"
+
 /* Prototypes for local functions.  */
 static void cleanup_sigint_signal_handler (void *dummy);
 static void initialize_sigint_signal_handler (void);
@@ -5366,6 +5368,41 @@
   return 0;
 }
 
+static int
+remote_start_tracepoints (char *args, int from_tty)
+{
+  fprintf_unfiltered (gdb_stdout, "remote to_start_tracepoints\n");
+  return 0;
+}
+
+static int
+remote_stop_tracepoints (char *args, int from_tty)
+{
+  fprintf_unfiltered (gdb_stdout, "remote to_stop_tracepoints\n");
+  return 0;
+}
+
+static int
+remote_tracepoint_status (char *args, int from_tty)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf = alloca (rs->remote_packet_size);
+
+  if (from_tty && info_verbose)
+    fprintf_unfiltered (gdb_stdout, "remote to_tracepoint_status\n");
+  putpkt ("qTStatus");
+  /* FIXME: How about async?  See tracepoint.c, get_noisy_reply.  */
+  getpkt (buf, rs->remote_packet_size, 0);
+
+  if (buf[0] != 'T' ||
+      (buf[1] != '0' && buf[1] != '1'))
+    return 0;	/* Target does not support.  */
+
+  /* Exported for use by the GUI.  */
+  trace_running_p = (buf[1] == '1');
+  return 1;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -5413,6 +5450,9 @@
   remote_ops.to_has_registers = 1;
   remote_ops.to_has_execution = 1;
   remote_ops.to_has_thread_control = tc_schedlock;	/* can lock scheduler */
+  remote_ops.to_start_tracepoints = remote_start_tracepoints;
+  remote_ops.to_stop_tracepoints = remote_stop_tracepoints;
+  remote_ops.to_tracepoint_status = remote_tracepoint_status;
   remote_ops.to_magic = OPS_MAGIC;
 }
 
@@ -5542,6 +5582,9 @@
   remote_async_ops.to_is_async_p = remote_is_async_p;
   remote_async_ops.to_async = remote_async;
   remote_async_ops.to_async_mask_value = 1;
+  remote_async_ops.to_start_tracepoints = remote_start_tracepoints;
+  remote_async_ops.to_stop_tracepoints = remote_stop_tracepoints;
+  remote_async_ops.to_tracepoint_status = remote_tracepoint_status;
   remote_async_ops.to_magic = OPS_MAGIC;
 }
 
diff --git a/gdb/target.c b/gdb/target.c
index a3894a2..106ca34 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -38,6 +38,7 @@
 #include "regcache.h"
 #include "gdb_assert.h"
 #include "gdbcore.h"
+#include "tracepoint.h"
 
 static void target_info (char *, int);
 
@@ -456,6 +457,10 @@
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
+      INHERIT (to_start_tracepoints, t);
+      INHERIT (to_stop_tracepoints, t);
+      INHERIT (to_tracepoint_status, t);
+     
       INHERIT (to_magic, t);
     }
 #undef INHERIT
@@ -636,6 +641,16 @@
   de_fault (to_async, 
 	    (void (*) (void (*) (enum inferior_event_type, void*), void*)) 
 	    tcomplain);
+  de_fault (to_start_tracepoints, 
+	    (int (*) (char *, int))
+	    return_zero);
+  de_fault (to_stop_tracepoints, 
+	    (int (*) (char *, int))
+	    return_zero);
+  de_fault (to_tracepoint_status, 
+	    (int (*) (char *, int))
+	    return_zero);
+
 #undef de_fault
 
   /* Finally, position the target-stack beneath the squashed
@@ -1847,6 +1862,36 @@
   return NULL;
 }
 
+/* Generic fallback method for tracepoints: start tracepoint experiment.  */
+static int
+default_start_tracepoints (char *args, int from_tty)
+{
+  if (info_verbose)
+    fprintf_unfiltered (gdb_stdout, "default to_start_tracepoints\n");
+
+  return trace_default_start (args, from_tty);
+}
+
+/* Generic fallback method for tracepoints: stop tracepoint experiment.  */
+static int
+default_stop_tracepoints (char *args, int from_tty)
+{
+  if (info_verbose)
+    fprintf_unfiltered (gdb_stdout, "default to_stop_tracepoints\n");
+
+  return trace_default_stop (args, from_tty);
+}
+
+/* Generic fallback method for tracepoints: tracepoint experiment status.  */
+static int
+default_tracepoint_status (char *args, int from_tty)
+{
+  if (info_verbose)
+    fprintf_unfiltered (gdb_stdout, "default to_tracepoint_status\n");
+
+  return trace_default_status (args, from_tty);
+}
+
 /* Set up the handful of non-empty slots needed by the dummy target
    vector.  */
 
@@ -1863,6 +1908,9 @@
   dummy_target.to_find_memory_regions = dummy_find_memory_regions;
   dummy_target.to_make_corefile_notes = dummy_make_corefile_notes;
   dummy_target.to_xfer_partial = default_xfer_partial;
+  dummy_target.to_start_tracepoints = default_start_tracepoints;
+  dummy_target.to_stop_tracepoints = default_stop_tracepoints;
+  dummy_target.to_tracepoint_status = default_tracepoint_status;
   dummy_target.to_magic = OPS_MAGIC;
 }
 
@@ -2530,6 +2578,36 @@
   return exec_file;
 }
 
+static int
+debug_to_start_tracepoints (char *args, int from_tty)
+{
+  int ret = debug_target.to_start_tracepoints (args, from_tty);
+
+  fprintf_unfiltered (gdb_stdout, 
+		      "target to_start_tracepoints returns %d\n", ret);
+  return ret;
+}
+
+static int
+debug_to_stop_tracepoints (char *args, int from_tty)
+{
+  int ret = debug_target.to_stop_tracepoints (args, from_tty);
+
+  fprintf_unfiltered (gdb_stdout, 
+		      "target to_stop_tracepoints returns %d\n", ret);
+  return ret;
+}
+
+static int
+debug_to_tracepoint_status (char *args, int from_tty)
+{
+  int ret = debug_target.to_tracepoint_status (args, from_tty);
+
+  fprintf_unfiltered (gdb_stdout, 
+		      "target to_tracepoint_status returns %d\n", ret);
+  return ret;
+}
+
 static void
 setup_target_debug (void)
 {
@@ -2590,6 +2668,10 @@
   current_target.to_get_current_exception_event = debug_to_get_current_exception_event;
   current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
 
+  current_target.to_start_tracepoints = debug_to_start_tracepoints;
+  current_target.to_stop_tracepoints  = debug_to_stop_tracepoints;
+  current_target.to_tracepoint_status = debug_to_tracepoint_status;
+
 }
 
 
diff --git a/gdb/target.h b/gdb/target.h
index 582fa78..eb75f46 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -422,6 +422,13 @@
 				gdb_byte *readbuf, const gdb_byte *writebuf,
 				ULONGEST offset, LONGEST len);
 
+    /* Tracepoint start.  */
+    int (*to_start_tracepoints) (char *, int);
+    /* Tracepoint stop.  */
+    int (*to_stop_tracepoints) (char *, int);
+    /* Tracepoint status.  */
+    int (*to_tracepoint_status) (char *, int);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1067,6 +1074,14 @@
 #define target_stopped_data_address_p(CURRENT_TARGET) (1)
 #endif
 
+#define target_start_tracepoints(ARGS, FROM_TTY) \
+     (*current_target.to_start_tracepoints) (ARGS, FROM_TTY)
+#define target_stop_tracepoints(ARGS, FROM_TTY) \
+     (*current_target.to_stop_tracepoints) (ARGS, FROM_TTY)
+#define target_tracepoint_status(ARGS, FROM_TTY) \
+     (*current_target.to_tracepoint_status) (ARGS, FROM_TTY)
+
+
 /* This will only be defined by a target that supports catching vfork events,
    such as HP-UX.
 
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index b1be03f..0522e45 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -1787,6 +1787,9 @@
     }
 }
 
+unsigned long trace_running_p;
+static FILE *checkpoint_file;
+
 /* tstart command:
 
    Tell target to clear any previous trace experiment.
@@ -1794,9 +1797,44 @@
    to the target.  If no errors, 
    Tell target to start a new trace experiment.  */
 
+extern int
+trace_default_start (char *args, int from_tty)
+{
+  if (checkpoint_file == NULL)
+    error (_("\
+You must open a tracepoint file to use the default tracepoint\n\
+method.  This will enable gdb to save trace data into a file.\n\n\
+See 'help open-tracepoint-file'."));
+
+  if (from_tty && info_verbose)
+    fprintf_filtered (gdb_stdout, "default trace start\n");
+  set_traceframe_num (-1);	/* All old traceframes invalidated.  */
+  set_tracepoint_num (-1);
+  set_traceframe_context (-1);
+  trace_running_p = 1;
+  if (deprecated_trace_start_stop_hook)
+    deprecated_trace_start_stop_hook (1, from_tty);
+
+  return 1;	/* Handled.  */
+}
+
 static void
 trace_start_command (char *args, int from_tty)
 {
+#if 1
+  if (!target_start_tracepoints (args, from_tty))
+    {
+      if (!default_trace_method)
+	if (query (_("Target tracepoint support not active.  Use default method? ")))
+	  default_trace_method++;
+
+      if (default_trace_method)
+	trace_default_start (args, from_tty);
+      else if (from_tty)
+	fprintf_filtered (gdb_stdout, "Cancelled.\n");
+    }
+  return;
+#else
   struct tracepoint *t;
   char buf[2048];
   char **tdp_actions;
@@ -1903,12 +1941,47 @@
   trace_running_p = 1;
   if (deprecated_trace_start_stop_hook)
     deprecated_trace_start_stop_hook (1, from_tty);
+#endif
 }
 
-/* tstop command */
+/* tstop command:
+   Tell the target to stop collecting trace data.  */
+
+extern int
+trace_default_stop (char *args, int from_tty)
+{
+  if (checkpoint_file == NULL)
+    error (_("\
+You must open a tracepoint file to use the default tracepoint\n\
+method.  This will enable gdb to save trace data into a file.\n\n\
+See 'help open-tracepoint-file'."));
+
+  if (from_tty && info_verbose)
+    fprintf_filtered (gdb_stdout, "default trace stop\n");
+  trace_running_p = 0;
+  if (deprecated_trace_start_stop_hook)
+    deprecated_trace_start_stop_hook (0, from_tty);
+
+  return 1;	/* Handled.  */
+}
+
 static void
 trace_stop_command (char *args, int from_tty)
 {
+#if 1
+  if (!target_stop_tracepoints (args, from_tty))
+    {
+      if (!default_trace_method)
+	if (query (_("Target tracepoint support not active.  Use default method? ")))
+	  default_trace_method++;
+
+      if (default_trace_method)
+	trace_default_stop (args, from_tty);
+      else
+	fprintf_filtered (gdb_stdout, "Cancelled.\n");
+    }
+  return;
+#else
   if (default_trace_method)
     {
       /* Default implementation.  */
@@ -1931,14 +2004,47 @@
   trace_running_p = 0;
   if (deprecated_trace_start_stop_hook)
     deprecated_trace_start_stop_hook (0, from_tty);
+#endif
 }
 
-unsigned long trace_running_p;
+/* tstatus command:
+   Report whether trace is running.   */
 
-/* tstatus command */
+extern int
+trace_default_status (char *args, int from_tty)
+{
+  if (checkpoint_file == NULL)
+    error (_("\
+You must open a tracepoint file to use the default tracepoint\n\
+method.  This will enable gdb to save trace data into a file.\n\n\
+See 'help open-tracepoint-file'."));
+
+  if (from_tty && info_verbose)
+    fprintf_filtered (gdb_stdout, "default trace status\n");
+
+  fprintf_filtered (gdb_stdout, "Trace is %s.\n",
+		    trace_running_p ? "on" : "off");
+
+  return 1;	/* Handled.  */
+}
+
 static void
 trace_status_command (char *args, int from_tty)
 {
+#if 1
+  if (!target_tracepoint_status (args, from_tty))
+    {
+      if (!default_trace_method)
+	if (query (_("Target tracepoint support not active.  Use default method? ")))
+	  default_trace_method++;
+
+      if (default_trace_method)
+	trace_default_status (args, from_tty);
+      else
+	fprintf_filtered (gdb_stdout, "Cancelled.\n");
+    }
+  return;
+#else
   if (default_trace_method)
     {
       printf_filtered ("Trace is %s.\n", trace_running_p ? "on" : "off");
@@ -1959,6 +2065,7 @@
     {
       error (_("Target does not implement this command (tstatus)."));
     }
+#endif
 }
 
 /* Worker function for the various flavors of the tfind command.  */
@@ -2754,7 +2861,6 @@
   return traceframe_number;
 }
 
-static FILE *checkpoint_file;
 static int tracepoint_method;
 
 static void
@@ -3122,14 +3228,14 @@
 checkpoint_open (char *args, int from_tty)
 {
   if (args == NULL || *args == '\0')
-    error ("Argument required: checkpoint file name.");
+    error ("Argument required: filename for tracepoint/checkpoint data.");
 
   if ((checkpoint_file = fopen (args, "w")) == NULL)
     error ("Could not open checkpoint file %s for output.", args);
 
   fprintf (checkpoint_file, "CHECKPOINT FILE\n");
   if (from_tty)
-    fprintf_filtered (gdb_stdout, "File '%s' open for checkpoints.\n",
+    fprintf_filtered (gdb_stdout, "File '%s' open for trace/checkpoints.\n",
 		      args);
 }
 
@@ -3212,6 +3318,11 @@
 Argument is filename.");
   set_cmd_completer (c, filename_completer);
 
+  c = add_com ("open-tracepoint", class_trace, checkpoint_open, "\
+Open output file for tracepoints.\n\
+Argument is filename.");
+  set_cmd_completer (c, filename_completer);
+
   c = add_com ("close-checkpoint", class_trace, checkpoint_close, "\
 Close checkpoint file.\n\
 No arguments, since only one checkpoint file may be open at a time.");
diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h
index ab57895..cce37e5 100644
--- a/gdb/tracepoint.h
+++ b/gdb/tracepoint.h
@@ -25,6 +25,10 @@
 
 extern int default_trace_method;
 extern int tracepoint_event_p (void);
+extern int trace_default_start (char *, int);
+extern int trace_default_stop (char *, int);
+extern int trace_default_status (char *, int);
+extern unsigned long trace_running_p;
 
 /* Most of what follows is not meant for export.
    They're just forward declarations for internal use in tracepoint.c.  */
@@ -119,8 +123,6 @@
 
 extern struct tracepoint *tracepoint_chain;
 
-extern unsigned long trace_running_p;
-
 /* A hook used to notify the UI of tracepoint operations.  */
 
 void (*deprecated_create_tracepoint_hook) (struct tracepoint *);