gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / record.c
index b64f3bc6d974bc19e0f5b75cee138b7d0b987b77..759395d5bcd865e1a22654538c514e546835cb75 100644 (file)
@@ -1,6 +1,6 @@
 /* Process record and replay target for GDB, the GNU debugger.
 
 /* Process record and replay target for GDB, the GNU debugger.
 
-   Copyright (C) 2008-2013 Free Software Foundation, Inc.
+   Copyright (C) 2008-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -21,9 +21,9 @@
 #include "gdbcmd.h"
 #include "completer.h"
 #include "record.h"
 #include "gdbcmd.h"
 #include "completer.h"
 #include "record.h"
-#include "observer.h"
+#include "observable.h"
 #include "inferior.h"
 #include "inferior.h"
-#include "common/common-utils.h"
+#include "gdbsupport/common-utils.h"
 #include "cli/cli-utils.h"
 #include "disasm.h"
 
 #include "cli/cli-utils.h"
 #include "disasm.h"
 
@@ -48,6 +48,7 @@ static unsigned int record_call_history_size = 10;
 static unsigned int record_call_history_size_setshow_var;
 
 struct cmd_list_element *record_cmdlist = NULL;
 static unsigned int record_call_history_size_setshow_var;
 
 struct cmd_list_element *record_cmdlist = NULL;
+struct cmd_list_element *record_goto_cmdlist = NULL;
 struct cmd_list_element *set_record_cmdlist = NULL;
 struct cmd_list_element *show_record_cmdlist = NULL;
 struct cmd_list_element *info_record_cmdlist = NULL;
 struct cmd_list_element *set_record_cmdlist = NULL;
 struct cmd_list_element *show_record_cmdlist = NULL;
 struct cmd_list_element *info_record_cmdlist = NULL;
@@ -56,18 +57,12 @@ struct cmd_list_element *info_record_cmdlist = NULL;
   if (record_debug)                                                    \
     fprintf_unfiltered (gdb_stdlog, "record: " msg "\n", ##args)
 
   if (record_debug)                                                    \
     fprintf_unfiltered (gdb_stdlog, "record: " msg "\n", ##args)
 
-/* Find the record target in the target stack.  */
+/* See record.h.  */
 
 
-static struct target_ops *
+struct target_ops *
 find_record_target (void)
 {
 find_record_target (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_stratum == record_stratum)
-      return t;
-
-  return NULL;
+  return find_target_at (record_stratum);
 }
 
 /* Check that recording is active.  Throw an error, if it isn't.  */
 }
 
 /* Check that recording is active.  Throw an error, if it isn't.  */
@@ -80,13 +75,66 @@ require_record_target (void)
   t = find_record_target ();
   if (t == NULL)
     error (_("No record target is currently active.\n"
   t = find_record_target ();
   if (t == NULL)
     error (_("No record target is currently active.\n"
-            "Use one of the \"target record-<tab><tab>\" commands first."));
+            "Use one of the \"target record-<TAB><TAB>\" commands first."));
 
   return t;
 }
 
 /* See record.h.  */
 
 
   return t;
 }
 
 /* See record.h.  */
 
+void
+record_preopen (void)
+{
+  /* Check if a record target is already running.  */
+  if (find_record_target () != NULL)
+    error (_("The process is already being recorded.  Use \"record stop\" to "
+            "stop recording first."));
+}
+
+/* See record.h.  */
+
+void
+record_start (const char *method, const char *format, int from_tty)
+{
+  if (method == NULL)
+    {
+      if (format == NULL)
+       execute_command_to_string ("record", from_tty, false);
+      else
+       error (_("Invalid format."));
+    }
+  else if (strcmp (method, "full") == 0)
+    {
+      if (format == NULL)
+       execute_command_to_string ("record full", from_tty, false);
+      else
+       error (_("Invalid format."));
+    }
+  else if (strcmp (method, "btrace") == 0)
+    {
+      if (format == NULL)
+       execute_command_to_string ("record btrace", from_tty, false);
+      else if (strcmp (format, "bts") == 0)
+       execute_command_to_string ("record btrace bts", from_tty, false);
+      else if (strcmp (format, "pt") == 0)
+       execute_command_to_string ("record btrace pt", from_tty, false);
+      else
+       error (_("Invalid format."));
+    }
+  else
+    error (_("Invalid method."));
+}
+
+/* See record.h.  */
+
+void
+record_stop (int from_tty)
+{
+  execute_command_to_string ("record stop", from_tty, false);
+}
+
+/* See record.h.  */
+
 int
 record_read_memory (struct gdbarch *gdbarch,
                    CORE_ADDR memaddr, gdb_byte *myaddr,
 int
 record_read_memory (struct gdbarch *gdbarch,
                    CORE_ADDR memaddr, gdb_byte *myaddr,
@@ -106,10 +154,9 @@ record_read_memory (struct gdbarch *gdbarch,
 static void
 record_stop (struct target_ops *t)
 {
 static void
 record_stop (struct target_ops *t)
 {
-  DEBUG ("stop %s", t->to_shortname);
+  DEBUG ("stop %s", t->shortname ());
 
 
-  if (t->to_stop_recording != NULL)
-    t->to_stop_recording ();
+  t->stop_recording ();
 }
 
 /* Unpush the record target.  */
 }
 
 /* Unpush the record target.  */
@@ -117,7 +164,7 @@ record_stop (struct target_ops *t)
 static void
 record_unpush (struct target_ops *t)
 {
 static void
 record_unpush (struct target_ops *t)
 {
-  DEBUG ("unpush %s", t->to_shortname);
+  DEBUG ("unpush %s", t->shortname ());
 
   unpush_target (t);
 }
 
   unpush_target (t);
 }
@@ -125,11 +172,11 @@ record_unpush (struct target_ops *t)
 /* See record.h.  */
 
 void
 /* See record.h.  */
 
 void
-record_disconnect (struct target_ops *t, char *args, int from_tty)
+record_disconnect (struct target_ops *t, const char *args, int from_tty)
 {
 {
-  gdb_assert (t->to_stratum == record_stratum);
+  gdb_assert (t->stratum () == record_stratum);
 
 
-  DEBUG ("disconnect %s", t->to_shortname);
+  DEBUG ("disconnect %s", t->shortname ());
 
   record_stop (t);
   record_unpush (t);
 
   record_stop (t);
   record_unpush (t);
@@ -140,16 +187,16 @@ record_disconnect (struct target_ops *t, char *args, int from_tty)
 /* See record.h.  */
 
 void
 /* See record.h.  */
 
 void
-record_detach (struct target_ops *t, char *args, int from_tty)
+record_detach (struct target_ops *t, inferior *inf, int from_tty)
 {
 {
-  gdb_assert (t->to_stratum == record_stratum);
+  gdb_assert (t->stratum () == record_stratum);
 
 
-  DEBUG ("detach %s", t->to_shortname);
+  DEBUG ("detach %s", t->shortname ());
 
   record_stop (t);
   record_unpush (t);
 
 
   record_stop (t);
   record_unpush (t);
 
-  target_detach (args, from_tty);
+  target_detach (inf, from_tty);
 }
 
 /* See record.h.  */
 }
 
 /* See record.h.  */
@@ -157,15 +204,15 @@ record_detach (struct target_ops *t, char *args, int from_tty)
 void
 record_mourn_inferior (struct target_ops *t)
 {
 void
 record_mourn_inferior (struct target_ops *t)
 {
-  gdb_assert (t->to_stratum == record_stratum);
+  gdb_assert (t->stratum () == record_stratum);
 
 
-  DEBUG ("mourn inferior %s", t->to_shortname);
+  DEBUG ("mourn inferior %s", t->shortname ());
 
   /* It is safer to not stop recording.  Resources will be freed when
      threads are discarded.  */
   record_unpush (t);
 
 
   /* It is safer to not stop recording.  Resources will be freed when
      threads are discarded.  */
   record_unpush (t);
 
-  target_mourn_inferior ();
+  target_mourn_inferior (inferior_ptid);
 }
 
 /* See record.h.  */
 }
 
 /* See record.h.  */
@@ -173,9 +220,9 @@ record_mourn_inferior (struct target_ops *t)
 void
 record_kill (struct target_ops *t)
 {
 void
 record_kill (struct target_ops *t)
 {
-  gdb_assert (t->to_stratum == record_stratum);
+  gdb_assert (t->stratum () == record_stratum);
 
 
-  DEBUG ("kill %s", t->to_shortname);
+  DEBUG ("kill %s", t->shortname ());
 
   /* It is safer to not stop recording.  Resources will be freed when
      threads are discarded.  */
 
   /* It is safer to not stop recording.  Resources will be freed when
      threads are discarded.  */
@@ -184,6 +231,26 @@ record_kill (struct target_ops *t)
   target_kill ();
 }
 
   target_kill ();
 }
 
+/* See record.h.  */
+
+int
+record_check_stopped_by_breakpoint (const address_space *aspace,
+                                   CORE_ADDR pc,
+                                   enum target_stop_reason *reason)
+{
+  if (breakpoint_inserted_here_p (aspace, pc))
+    {
+      if (hardware_breakpoint_inserted_here_p (aspace, pc))
+       *reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
+      else
+       *reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
+      return 1;
+    }
+
+  *reason = TARGET_STOPPED_BY_NO_REASON;
+  return 0;
+}
+
 /* Implement "show record debug" command.  */
 
 static void
 /* Implement "show record debug" command.  */
 
 static void
@@ -197,7 +264,7 @@ show_record_debug (struct ui_file *file, int from_tty,
 /* Alias for "target record".  */
 
 static void
 /* Alias for "target record".  */
 
 static void
-cmd_record_start (char *args, int from_tty)
+cmd_record_start (const char *args, int from_tty)
 {
   execute_command ("target record-full", from_tty);
 }
 {
   execute_command ("target record-full", from_tty);
 }
@@ -206,11 +273,11 @@ cmd_record_start (char *args, int from_tty)
    of replay until the end.  */
 
 static void
    of replay until the end.  */
 
 static void
-cmd_record_delete (char *args, int from_tty)
+cmd_record_delete (const char *args, int from_tty)
 {
   require_record_target ();
 
 {
   require_record_target ();
 
-  if (!target_record_is_replaying ())
+  if (!target_record_is_replaying (inferior_ptid))
     {
       printf_unfiltered (_("Already at end of record list.\n"));
       return;
     {
       printf_unfiltered (_("Already at end of record list.\n"));
       return;
@@ -232,7 +299,7 @@ cmd_record_delete (char *args, int from_tty)
 /* Implement the "stoprecord" or "record stop" command.  */
 
 static void
 /* Implement the "stoprecord" or "record stop" command.  */
 
 static void
-cmd_record_stop (char *args, int from_tty)
+cmd_record_stop (const char *args, int from_tty)
 {
   struct target_ops *t;
 
 {
   struct target_ops *t;
 
@@ -244,31 +311,14 @@ cmd_record_stop (char *args, int from_tty)
   printf_unfiltered (_("Process record is stopped and all execution "
                       "logs are deleted.\n"));
 
   printf_unfiltered (_("Process record is stopped and all execution "
                       "logs are deleted.\n"));
 
-  observer_notify_record_changed (current_inferior (), 0);
-}
-
-/* The "set record" command.  */
-
-static void
-set_record_command (char *args, int from_tty)
-{
-  printf_unfiltered (_("\"set record\" must be followed "
-                      "by an apporpriate subcommand.\n"));
-  help_list (set_record_cmdlist, "set record ", all_commands, gdb_stdout);
+  gdb::observers::record_changed.notify (current_inferior (), 0, NULL, NULL);
 }
 
 }
 
-/* The "show record" command.  */
-
-static void
-show_record_command (char *args, int from_tty)
-{
-  cmd_show_list (show_record_cmdlist, from_tty, "");
-}
 
 /* The "info record" command.  */
 
 static void
 
 /* The "info record" command.  */
 
 static void
-info_record_command (char *args, int from_tty)
+info_record_command (const char *args, int from_tty)
 {
   struct target_ops *t;
 
 {
   struct target_ops *t;
 
@@ -279,17 +329,17 @@ info_record_command (char *args, int from_tty)
       return;
     }
 
       return;
     }
 
-  printf_filtered (_("Active record target: %s\n"), t->to_shortname);
-  if (t->to_info_record != NULL)
-    t->to_info_record ();
+  printf_filtered (_("Active record target: %s\n"), t->shortname ());
+  t->info_record ();
 }
 
 /* The "record save" command.  */
 
 static void
 }
 
 /* The "record save" command.  */
 
 static void
-cmd_record_save (char *args, int from_tty)
+cmd_record_save (const char *args, int from_tty)
 {
 {
-  char *recfilename, recfilename_buffer[40];
+  const char *recfilename;
+  char recfilename_buffer[40];
 
   require_record_target ();
 
 
   require_record_target ();
 
@@ -299,50 +349,74 @@ cmd_record_save (char *args, int from_tty)
     {
       /* Default recfile name is "gdb_record.PID".  */
       xsnprintf (recfilename_buffer, sizeof (recfilename_buffer),
     {
       /* Default recfile name is "gdb_record.PID".  */
       xsnprintf (recfilename_buffer, sizeof (recfilename_buffer),
-                "gdb_record.%d", PIDGET (inferior_ptid));
+                "gdb_record.%d", inferior_ptid.pid ());
       recfilename = recfilename_buffer;
     }
 
   target_save_record (recfilename);
 }
 
       recfilename = recfilename_buffer;
     }
 
   target_save_record (recfilename);
 }
 
+/* See record.h.  */
+
+void
+record_goto (const char *arg)
+{
+  ULONGEST insn;
+
+  if (arg == NULL || *arg == '\0')
+    error (_("Command requires an argument (insn number to go to)."));
+
+  insn = parse_and_eval_long (arg);
+
+  require_record_target ();
+  target_goto_record (insn);
+}
+
 /* "record goto" command.  Argument is an instruction number,
    as given by "info record".
 
    Rewinds the recording (forward or backward) to the given instruction.  */
 
 /* "record goto" command.  Argument is an instruction number,
    as given by "info record".
 
    Rewinds the recording (forward or backward) to the given instruction.  */
 
-void
-cmd_record_goto (char *arg, int from_tty)
+static void
+cmd_record_goto (const char *arg, int from_tty)
+{
+  record_goto (arg);
+}
+
+/* The "record goto begin" command.  */
+
+static void
+cmd_record_goto_begin (const char *arg, int from_tty)
 {
 {
+  if (arg != NULL && *arg != '\0')
+    error (_("Junk after argument: %s."), arg);
+
   require_record_target ();
   require_record_target ();
+  target_goto_record_begin ();
+}
 
 
-  if (arg == NULL || *arg == '\0')
-    error (_("Command requires an argument (insn number to go to)."));
+/* The "record goto end" command.  */
 
 
-  if (strncmp (arg, "start", strlen ("start")) == 0
-      || strncmp (arg, "begin", strlen ("begin")) == 0)
-    target_goto_record_begin ();
-  else if (strncmp (arg, "end", strlen ("end")) == 0)
-    target_goto_record_end ();
-  else
-    {
-      ULONGEST insn;
+static void
+cmd_record_goto_end (const char *arg, int from_tty)
+{
+  if (arg != NULL && *arg != '\0')
+    error (_("Junk after argument: %s."), arg);
 
 
-      insn = parse_and_eval_long (arg);
-      target_goto_record (insn);
-    }
+  require_record_target ();
+  target_goto_record_end ();
 }
 
 /* Read an instruction number from an argument string.  */
 
 static ULONGEST
 }
 
 /* Read an instruction number from an argument string.  */
 
 static ULONGEST
-get_insn_number (char **arg)
+get_insn_number (const char **arg)
 {
   ULONGEST number;
   const char *begin, *end, *pos;
 
   begin = *arg;
 {
   ULONGEST number;
   const char *begin, *end, *pos;
 
   begin = *arg;
-  pos = skip_spaces_const (begin);
+  pos = skip_spaces (begin);
 
   if (!isdigit (*pos))
     error (_("Expected positive number, got: %s."), pos);
 
   if (!isdigit (*pos))
     error (_("Expected positive number, got: %s."), pos);
@@ -357,23 +431,25 @@ get_insn_number (char **arg)
 /* Read a context size from an argument string.  */
 
 static int
 /* Read a context size from an argument string.  */
 
 static int
-get_context_size (char **arg)
+get_context_size (const char **arg)
 {
 {
-  char *pos;
-  int number;
+  const char *pos;
+  char *end;
 
   pos = skip_spaces (*arg);
 
   if (!isdigit (*pos))
     error (_("Expected positive number, got: %s."), pos);
 
 
   pos = skip_spaces (*arg);
 
   if (!isdigit (*pos))
     error (_("Expected positive number, got: %s."), pos);
 
-  return strtol (pos, arg, 10);
+  long result = strtol (pos, &end, 10);
+  *arg = end;
+  return result;
 }
 
 /* Complain about junk at the end of an argument string.  */
 
 static void
 }
 
 /* Complain about junk at the end of an argument string.  */
 
 static void
-no_chunk (char *arg)
+no_chunk (const char *arg)
 {
   if (*arg != 0)
     error (_("Junk after argument: %s."), arg);
 {
   if (*arg != 0)
     error (_("Junk after argument: %s."), arg);
@@ -381,11 +457,11 @@ no_chunk (char *arg)
 
 /* Read instruction-history modifiers from an argument string.  */
 
 
 /* Read instruction-history modifiers from an argument string.  */
 
-static int
-get_insn_history_modifiers (char **arg)
+static gdb_disassembly_flags
+get_insn_history_modifiers (const char **arg)
 {
 {
-  int modifiers;
-  char *args;
+  gdb_disassembly_flags modifiers;
+  const char *args;
 
   modifiers = 0;
   args = *arg;
 
   modifiers = 0;
   args = *arg;
@@ -411,6 +487,7 @@ get_insn_history_modifiers (char **arg)
          switch (*args)
            {
            case 'm':
          switch (*args)
            {
            case 'm':
+           case 's':
              modifiers |= DISASSEMBLY_SOURCE;
              modifiers |= DISASSEMBLY_FILENAME;
              break;
              modifiers |= DISASSEMBLY_SOURCE;
              modifiers |= DISASSEMBLY_FILENAME;
              break;
@@ -442,32 +519,30 @@ get_insn_history_modifiers (char **arg)
    meaning unlimited.  The target interfaces works with signed int
    though, to indicate direction, so map "unlimited" to INT_MAX, which
    is about the same as unlimited in practice.  If the user does have
    meaning unlimited.  The target interfaces works with signed int
    though, to indicate direction, so map "unlimited" to INT_MAX, which
    is about the same as unlimited in practice.  If the user does have
-   a log that huge, she can can fetch it in chunks across several
-   requests, but she'll likely have other problems first...  */
+   a log that huge, she can fetch it in chunks across several requests,
+   but she'll likely have other problems first...  */
 
 static int
 
 static int
-command_size_to_target_size (unsigned int *command)
+command_size_to_target_size (unsigned int size)
 {
 {
-  gdb_assert (*command <= INT_MAX || *command == UINT_MAX);
+  gdb_assert (size <= INT_MAX || size == UINT_MAX);
 
 
-  if (record_call_history_size == UINT_MAX)
+  if (size == UINT_MAX)
     return INT_MAX;
   else
     return INT_MAX;
   else
-    return *command;
+    return size;
 }
 
 /* The "record instruction-history" command.  */
 
 static void
 }
 
 /* The "record instruction-history" command.  */
 
 static void
-cmd_record_insn_history (char *arg, int from_tty)
+cmd_record_insn_history (const char *arg, int from_tty)
 {
 {
-  int flags, size;
-
   require_record_target ();
 
   require_record_target ();
 
-  flags = get_insn_history_modifiers (&arg);
+  gdb_disassembly_flags flags = get_insn_history_modifiers (&arg);
 
 
-  size = command_size_to_target_size (&record_insn_history_size);
+  int size = command_size_to_target_size (record_insn_history_size);
 
   if (arg == NULL || *arg == 0 || strcmp (arg, "+") == 0)
     target_insn_history (size, flags);
 
   if (arg == NULL || *arg == 0 || strcmp (arg, "+") == 0)
     target_insn_history (size, flags);
@@ -523,14 +598,11 @@ cmd_record_insn_history (char *arg, int from_tty)
 
 /* Read function-call-history modifiers from an argument string.  */
 
 
 /* Read function-call-history modifiers from an argument string.  */
 
-static int
-get_call_history_modifiers (char **arg)
+static record_print_flags
+get_call_history_modifiers (const char **arg)
 {
 {
-  int modifiers;
-  char *args;
-
-  modifiers = 0;
-  args = *arg;
+  record_print_flags modifiers = 0;
+  const char *args = *arg;
 
   if (args == NULL)
     return modifiers;
 
   if (args == NULL)
     return modifiers;
@@ -553,10 +625,13 @@ get_call_history_modifiers (char **arg)
          switch (*args)
            {
            case 'l':
          switch (*args)
            {
            case 'l':
-             modifiers |= record_print_src_line;
+             modifiers |= RECORD_PRINT_SRC_LINE;
              break;
            case 'i':
              break;
            case 'i':
-             modifiers |= record_print_insn_range;
+             modifiers |= RECORD_PRINT_INSN_RANGE;
+             break;
+           case 'c':
+             modifiers |= RECORD_PRINT_INDENT_CALLS;
              break;
            default:
              error (_("Invalid modifier: %c."), *args);
              break;
            default:
              error (_("Invalid modifier: %c."), *args);
@@ -575,15 +650,13 @@ get_call_history_modifiers (char **arg)
 /* The "record function-call-history" command.  */
 
 static void
 /* The "record function-call-history" command.  */
 
 static void
-cmd_record_call_history (char *arg, int from_tty)
+cmd_record_call_history (const char *arg, int from_tty)
 {
 {
-  int flags, size;
-
   require_record_target ();
 
   require_record_target ();
 
-  flags = get_call_history_modifiers (&arg);
+  record_print_flags flags = get_call_history_modifiers (&arg);
 
 
-  size = command_size_to_target_size (&record_call_history_size);
+  int size = command_size_to_target_size (record_call_history_size);
 
   if (arg == NULL || *arg == 0 || strcmp (arg, "+") == 0)
     target_call_history (size, flags);
 
   if (arg == NULL || *arg == 0 || strcmp (arg, "+") == 0)
     target_call_history (size, flags);
@@ -643,7 +716,7 @@ cmd_record_call_history (char *arg, int from_tty)
    is the real setting the command allows changing.  */
 
 static void
    is the real setting the command allows changing.  */
 
 static void
-validate_history_size (unsigned int *command_var, int *setting)
+validate_history_size (unsigned int *command_var, unsigned int *setting)
 {
   if (*command_var != UINT_MAX && *command_var > INT_MAX)
     {
 {
   if (*command_var != UINT_MAX && *command_var > INT_MAX)
     {
@@ -663,7 +736,7 @@ validate_history_size (unsigned int *command_var, int *setting)
    [0..UINT_MAX].  See command_size_to_target_size.  */
 
 static void
    [0..UINT_MAX].  See command_size_to_target_size.  */
 
 static void
-set_record_insn_history_size (char *args, int from_tty,
+set_record_insn_history_size (const char *args, int from_tty,
                              struct cmd_list_element *c)
 {
   validate_history_size (&record_insn_history_size_setshow_var,
                              struct cmd_list_element *c)
 {
   validate_history_size (&record_insn_history_size_setshow_var,
@@ -675,18 +748,16 @@ set_record_insn_history_size (char *args, int from_tty,
    [0..UINT_MAX].  See command_size_to_target_size.  */
 
 static void
    [0..UINT_MAX].  See command_size_to_target_size.  */
 
 static void
-set_record_call_history_size (char *args, int from_tty,
+set_record_call_history_size (const char *args, int from_tty,
                              struct cmd_list_element *c)
 {
   validate_history_size (&record_call_history_size_setshow_var,
                         &record_call_history_size);
 }
 
                              struct cmd_list_element *c)
 {
   validate_history_size (&record_call_history_size_setshow_var,
                         &record_call_history_size);
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_record;
-
+void _initialize_record ();
 void
 void
-_initialize_record (void)
+_initialize_record ()
 {
   struct cmd_list_element *c;
 
 {
   struct cmd_list_element *c;
 
@@ -701,16 +772,16 @@ _initialize_record (void)
   add_setshow_uinteger_cmd ("instruction-history-size", no_class,
                            &record_insn_history_size_setshow_var, _("\
 Set number of instructions to print in \"record instruction-history\"."), _("\
   add_setshow_uinteger_cmd ("instruction-history-size", no_class,
                            &record_insn_history_size_setshow_var, _("\
 Set number of instructions to print in \"record instruction-history\"."), _("\
-Show number of instructions to print in \"record instruction-history\"."),
-                           NULL,
+Show number of instructions to print in \"record instruction-history\"."), _("\
+A size of \"unlimited\" means unlimited instructions.  The default is 10."),
                            set_record_insn_history_size, NULL,
                            &set_record_cmdlist, &show_record_cmdlist);
 
   add_setshow_uinteger_cmd ("function-call-history-size", no_class,
                            &record_call_history_size_setshow_var, _("\
 Set number of function to print in \"record function-call-history\"."), _("\
                            set_record_insn_history_size, NULL,
                            &set_record_cmdlist, &show_record_cmdlist);
 
   add_setshow_uinteger_cmd ("function-call-history-size", no_class,
                            &record_call_history_size_setshow_var, _("\
 Set number of function to print in \"record function-call-history\"."), _("\
-Show number of functions to print in \"record function-call-history\"."),
-                           NULL,
+Show number of functions to print in \"record function-call-history\"."), _("\
+A size of \"unlimited\" means unlimited lines.  The default is 10."),
                            set_record_call_history_size, NULL,
                            &set_record_cmdlist, &show_record_cmdlist);
 
                            set_record_call_history_size, NULL,
                            &set_record_cmdlist, &show_record_cmdlist);
 
@@ -720,23 +791,23 @@ Show number of functions to print in \"record function-call-history\"."),
   set_cmd_completer (c, filename_completer);
 
   add_com_alias ("rec", "record", class_obscure, 1);
   set_cmd_completer (c, filename_completer);
 
   add_com_alias ("rec", "record", class_obscure, 1);
-  add_prefix_cmd ("record", class_support, set_record_command,
-                 _("Set record options"), &set_record_cmdlist,
-                 "set record ", 0, &setlist);
+  add_basic_prefix_cmd ("record", class_support,
+                       _("Set record options."), &set_record_cmdlist,
+                       "set record ", 0, &setlist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &setlist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &setlist);
-  add_prefix_cmd ("record", class_support, show_record_command,
-                 _("Show record options"), &show_record_cmdlist,
-                 "show record ", 0, &showlist);
+  add_show_prefix_cmd ("record", class_support,
+                      _("Show record options."), &show_record_cmdlist,
+                      "show record ", 0, &showlist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &showlist);
   add_prefix_cmd ("record", class_support, info_record_command,
   add_alias_cmd ("rec", "record", class_obscure, 1, &showlist);
   add_prefix_cmd ("record", class_support, info_record_command,
-                 _("Info record options"), &info_record_cmdlist,
+                 _("Info record options."), &info_record_cmdlist,
                  "info record ", 0, &infolist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &infolist);
 
   c = add_cmd ("save", class_obscure, cmd_record_save,
               _("Save the execution log to a file.\n\
                  "info record ", 0, &infolist);
   add_alias_cmd ("rec", "record", class_obscure, 1, &infolist);
 
   c = add_cmd ("save", class_obscure, cmd_record_save,
               _("Save the execution log to a file.\n\
-Argument is optional filename.\n\
-Default filename is 'gdb_record.<process_id>'."),
+Usage: record save [FILENAME]\n\
+Default filename is 'gdb_record.PROCESS_ID'."),
               &record_cmdlist);
   set_cmd_completer (c, filename_completer);
 
               &record_cmdlist);
   set_cmd_completer (c, filename_completer);
 
@@ -751,14 +822,23 @@ Default filename is 'gdb_record.<process_id>'."),
            &record_cmdlist);
   add_alias_cmd ("s", "stop", class_obscure, 1, &record_cmdlist);
 
            &record_cmdlist);
   add_alias_cmd ("s", "stop", class_obscure, 1, &record_cmdlist);
 
-  add_cmd ("goto", class_obscure, cmd_record_goto, _("\
+  add_prefix_cmd ("goto", class_obscure, cmd_record_goto, _("\
 Restore the program to its state at instruction number N.\n\
 Argument is instruction number, as shown by 'info record'."),
 Restore the program to its state at instruction number N.\n\
 Argument is instruction number, as shown by 'info record'."),
-          &record_cmdlist);
+                 &record_goto_cmdlist, "record goto ", 1, &record_cmdlist);
+
+  add_cmd ("begin", class_obscure, cmd_record_goto_begin,
+          _("Go to the beginning of the execution log."),
+          &record_goto_cmdlist);
+  add_alias_cmd ("start", "begin", class_obscure, 1, &record_goto_cmdlist);
+
+  add_cmd ("end", class_obscure, cmd_record_goto_end,
+          _("Go to the end of the execution log."),
+          &record_goto_cmdlist);
 
   add_cmd ("instruction-history", class_obscure, cmd_record_insn_history, _("\
 Print disassembled instructions stored in the execution log.\n\
 
   add_cmd ("instruction-history", class_obscure, cmd_record_insn_history, _("\
 Print disassembled instructions stored in the execution log.\n\
-With a /m modifier, source lines are included (if available).\n\
+With a /m or /s modifier, source lines are included (if available).\n\
 With a /r modifier, raw instructions in hex are included.\n\
 With a /f modifier, function names are omitted.\n\
 With a /p modifier, current position markers are omitted.\n\
 With a /r modifier, raw instructions in hex are included.\n\
 With a /f modifier, function names are omitted.\n\
 With a /p modifier, current position markers are omitted.\n\
@@ -783,6 +863,7 @@ function.\n\
 Without modifiers, it prints the function name.\n\
 With a /l modifier, the source file and line number range is included.\n\
 With a /i modifier, the instruction number range is included.\n\
 Without modifiers, it prints the function name.\n\
 With a /l modifier, the source file and line number range is included.\n\
 With a /i modifier, the instruction number range is included.\n\
+With a /c modifier, the output is indented based on the call stack depth.\n\
 With no argument, prints ten more lines after the previous ten-line print.\n\
 \"record function-call-history -\" prints ten lines before a previous ten-line \
 print.\n\
 With no argument, prints ten more lines after the previous ten-line print.\n\
 \"record function-call-history -\" prints ten lines before a previous ten-line \
 print.\n\
This page took 0.034447 seconds and 4 git commands to generate.