diff --git a/gdb/event-top.c b/gdb/event-top.c
index 7377189..1e84fdf 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -634,8 +634,8 @@ command_line_append_input_line (struct buffer *cmd_line_buffer, char *rl)
    If REPEAT, handle command repetitions:
 
      - If the input command line is NOT empty, the command returned is
-       copied into the global 'saved_command_line' var so that it can
-       be repeated later.
+       copied into the 'ui->saved_command_line' var so that it can be
+       repeated later.
 
      - OTOH, if the input command line IS empty, return the previously
        saved command instead of the empty input line.
@@ -671,9 +671,9 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
 #define SERVER_COMMAND_PREFIX "server "
   if (startswith (cmd, SERVER_COMMAND_PREFIX))
     {
-      /* Note that we don't set `saved_command_line'.  Between this
-         and the check in dont_repeat, this insures that repeating
-         will still do the right thing.  */
+      /* Note that we don't set `ui->saved_command_line'.  Between
+         this and the check in dont_repeat, this insures that
+         repeating will still do the right thing.  */
       return cmd + strlen (SERVER_COMMAND_PREFIX);
     }
 
@@ -713,7 +713,7 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
   for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
     ;
   if (repeat && *p1 == '\0')
-    return saved_command_line;
+    return ui->saved_command_line;
 
   /* Add command to history if appropriate.  Note: lines consisting
      solely of comments are also added to the command history.  This
@@ -728,9 +728,9 @@ handle_line_of_input (struct buffer *cmd_line_buffer,
   /* Save into global buffer if appropriate.  */
   if (repeat)
     {
-      xfree (saved_command_line);
-      saved_command_line = xstrdup (cmd);
-      return saved_command_line;
+      xfree (ui->saved_command_line);
+      ui->saved_command_line = xstrdup (cmd);
+      return ui->saved_command_line;
     }
   else
     return cmd;
diff --git a/gdb/main.c b/gdb/main.c
index 835ae24..8fae552 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -522,8 +522,6 @@ captured_main_1 (struct captured_main_args *context)
   notice_open_fds ();
   save_original_signals_state ();
 
-  saved_command_line = (char *) xstrdup ("");
-
 #ifdef __MINGW32__
   /* Ensure stderr is unbuffered.  A Cygwin pty or pipe is implemented
      as a Windows pipe, and Windows buffers on pipes.  */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 017c7be..ec54658 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -49,37 +49,50 @@
 #include "format.h"
 #include "source.h"
 #include "common/byte-vector.h"
+#include "top.h"
 
 #ifdef TUI
 #include "tui/tui.h"		/* For tui_active et al.   */
 #endif
 
-/* Last specified output format.  */
+struct current_printcmd_info
+{
+  /* Last specified output format.  */
+  char last_format = 0;
 
-static char last_format = 0;
+  /* Last specified examination size.  'b', 'h', 'w' or `q'.  */
+  char last_size = 'w';
 
-/* Last specified examination size.  'b', 'h', 'w' or `q'.  */
+  /* Default address to examine next, and associated architecture.  */
+  struct gdbarch *next_gdbarch;
+  CORE_ADDR next_address;
 
-static char last_size = 'w';
+  /* Last address examined.  */
+  CORE_ADDR last_examine_address;
 
-/* Default address to examine next, and associated architecture.  */
+  /* Contents of last address examined.  This is not valid past the
+     end of the `x' command!  */
+  struct value *last_examine_value;
+};
 
-static struct gdbarch *next_gdbarch;
-static CORE_ADDR next_address;
+static current_printcmd_info &
+get_current_printcmd_info ()
+{
+  if (current_ui->curr_printcmd_info == NULL)
+    current_ui->curr_printcmd_info = new current_printcmd_info ();
+  return *current_ui->curr_printcmd_info;
+}
+
+void
+delete_current_printcmd_info (struct ui *ui)
+{
+  delete ui->curr_printcmd_info;
+}
 
 /* Number of delay instructions following current disassembled insn.  */
 
 static int branch_delay_insns;
 
-/* Last address examined.  */
-
-static CORE_ADDR last_examine_address;
-
-/* Contents of last address examined.
-   This is not valid past the end of the `x' command!  */
-
-static struct value *last_examine_value;
-
 /* Largest offset between a symbolic value and an address, that will be
    printed as `0x1234 <symbol+offset>'.  */
 
@@ -279,8 +292,10 @@ print_formatted (struct value *val, int size,
   struct type *type = check_typedef (value_type (val));
   int len = TYPE_LENGTH (type);
 
+  current_printcmd_info &ci = get_current_printcmd_info ();
+
   if (VALUE_LVAL (val) == lval_memory)
-    next_address = value_address (val) + len;
+    ci.next_address = value_address (val) + len;
 
   if (size)
     {
@@ -290,20 +305,20 @@ print_formatted (struct value *val, int size,
 	  {
 	    struct type *elttype = value_type (val);
 
-	    next_address = (value_address (val)
-			    + val_print_string (elttype, NULL,
-						value_address (val), -1,
-						stream, options) * len);
+	    ci.next_address = (value_address (val)
+			       + val_print_string (elttype, NULL,
+						   value_address (val), -1,
+						   stream, options) * len);
 	  }
 	  return;
 
 	case 'i':
 	  /* We often wrap here if there are long symbolic names.  */
 	  wrap_here ("    ");
-	  next_address = (value_address (val)
-			  + gdb_print_insn (get_type_arch (type),
-					    value_address (val), stream,
-					    &branch_delay_insns));
+	  ci.next_address = (value_address (val)
+			     + gdb_print_insn (get_type_arch (type),
+					       value_address (val), stream,
+					       &branch_delay_insns));
 	  return;
 	}
     }
@@ -500,10 +515,13 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
-  next_gdbarch = gdbarch;
-  next_address = addr;
+  current_printcmd_info &ci = get_current_printcmd_info ();
 
-  /* Make address available to the user as $_.  */
+  ci.next_gdbarch = gdbarch;
+  ci.next_address = addr;
+
+  /* Make address available to the user as $_.  FIXME: should instead
+     be a computed val, so that it works Per-UI.  */
   set_internalvar (lookup_internalvar ("_"),
 		   value_from_pointer (ptr_type, addr));
 }
@@ -976,8 +994,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
   format = fmt.format;
   size = fmt.size;
   count = fmt.count;
-  next_gdbarch = gdbarch;
-  next_address = addr;
+
+  current_printcmd_info &ci = get_current_printcmd_info ();
+
+  ci.next_gdbarch = gdbarch;
+  ci.next_address = addr;
 
   /* Instruction format implies fetch single bytes
      regardless of the specified size.
@@ -989,11 +1010,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
   if (size == 'a')
     {
       /* Pick the appropriate size for an address.  */
-      if (gdbarch_ptr_bit (next_gdbarch) == 64)
+      if (gdbarch_ptr_bit (ci.next_gdbarch) == 64)
 	size = 'g';
-      else if (gdbarch_ptr_bit (next_gdbarch) == 32)
+      else if (gdbarch_ptr_bit (ci.next_gdbarch) == 32)
 	size = 'w';
-      else if (gdbarch_ptr_bit (next_gdbarch) == 16)
+      else if (gdbarch_ptr_bit (ci.next_gdbarch) == 16)
 	size = 'h';
       else
 	/* Bad value for gdbarch_ptr_bit.  */
@@ -1002,13 +1023,13 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     }
 
   if (size == 'b')
-    val_type = builtin_type (next_gdbarch)->builtin_int8;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int8;
   else if (size == 'h')
-    val_type = builtin_type (next_gdbarch)->builtin_int16;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int16;
   else if (size == 'w')
-    val_type = builtin_type (next_gdbarch)->builtin_int32;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int32;
   else if (size == 'g')
-    val_type = builtin_type (next_gdbarch)->builtin_int64;
+    val_type = builtin_type (ci.next_gdbarch)->builtin_int64;
 
   if (format == 's')
     {
@@ -1017,9 +1038,9 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
       /* Search for "char16_t"  or "char32_t" types or fall back to 8-bit char
 	 if type is not found.  */
       if (size == 'h')
-	char_type = builtin_type (next_gdbarch)->builtin_char16;
+	char_type = builtin_type (ci.next_gdbarch)->builtin_char16;
       else if (size == 'w')
-	char_type = builtin_type (next_gdbarch)->builtin_char32;
+	char_type = builtin_type (ci.next_gdbarch)->builtin_char32;
       if (char_type)
         val_type = char_type;
       else
@@ -1028,7 +1049,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 	    warning (_("Unable to display strings with "
 		       "size '%c', using 'b' instead."), size);
 	  size = 'b';
-	  val_type = builtin_type (next_gdbarch)->builtin_int8;
+	  val_type = builtin_type (ci.next_gdbarch)->builtin_int8;
         }
     }
 
@@ -1051,26 +1072,26 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
       count = -count;
       if (format == 'i')
         {
-          next_address = find_instruction_backward (gdbarch, addr, count,
-                                                    &count);
+          ci.next_address = find_instruction_backward (gdbarch, addr, count,
+						       &count);
         }
       else if (format == 's')
         {
-          next_address = find_string_backward (gdbarch, addr, count,
-                                               TYPE_LENGTH (val_type),
-                                               &opts, &count);
+          ci.next_address = find_string_backward (gdbarch, addr, count,
+						  TYPE_LENGTH (val_type),
+						  &opts, &count);
         }
       else
         {
-          next_address = addr - count * TYPE_LENGTH (val_type);
+          ci.next_address = addr - count * TYPE_LENGTH (val_type);
         }
 
       /* The following call to print_formatted updates next_address in every
          iteration.  In backward case, we store the start address here
          and update next_address with it before exiting the function.  */
       addr_rewound = (format == 's'
-                      ? next_address - TYPE_LENGTH (val_type)
-                      : next_address);
+                      ? ci.next_address - TYPE_LENGTH (val_type)
+                      : ci.next_address);
       need_to_update_next_address = 1;
     }
 
@@ -1081,8 +1102,8 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     {
       QUIT;
       if (format == 'i')
-	fputs_filtered (pc_prefix (next_address), gdb_stdout);
-      print_address (next_gdbarch, next_address, gdb_stdout);
+	fputs_filtered (pc_prefix (ci.next_address), gdb_stdout);
+      print_address (ci.next_gdbarch, ci.next_address, gdb_stdout);
       printf_filtered (":");
       for (i = maxelts;
 	   i > 0 && count > 0;
@@ -1091,10 +1112,10 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 	  printf_filtered ("\t");
 	  /* Note that print_formatted sets next_address for the next
 	     object.  */
-	  last_examine_address = next_address;
+	  ci.last_examine_address = ci.next_address;
 
-	  if (last_examine_value)
-	    value_free (last_examine_value);
+	  if (ci.last_examine_value)
+	    value_free (ci.last_examine_value);
 
 	  /* The value to be displayed is not fetched greedily.
 	     Instead, to avoid the possibility of a fetched value not
@@ -1105,12 +1126,12 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 	     the disassembler be modified so that LAST_EXAMINE_VALUE
 	     is left with the byte sequence from the last complete
 	     instruction fetched from memory?  */
-	  last_examine_value = value_at_lazy (val_type, next_address);
+	  ci.last_examine_value = value_at_lazy (val_type, ci.next_address);
 
-	  if (last_examine_value)
-	    release_value (last_examine_value);
+	  if (ci.last_examine_value)
+	    release_value (ci.last_examine_value);
 
-	  print_formatted (last_examine_value, size, &opts, gdb_stdout);
+	  print_formatted (ci.last_examine_value, size, &opts, gdb_stdout);
 
 	  /* Display any branch delay slots following the final insn.  */
 	  if (format == 'i' && count == 1)
@@ -1121,7 +1142,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     }
 
   if (need_to_update_next_address)
-    next_address = addr_rewound;
+    ci.next_address = addr_rewound;
 }
 
 static void
@@ -1149,9 +1170,12 @@ print_command_parse_format (const char **expp, const char *cmdname,
   if (exp && *exp == '/')
     {
       exp++;
-      *fmtp = decode_format (&exp, last_format, 0);
+
+      current_printcmd_info &ci = get_current_printcmd_info ();
+
+      *fmtp = decode_format (&exp, ci.last_format, 0);
       validate_format (*fmtp, cmdname);
-      last_format = fmtp->format;
+      ci.last_format = fmtp->format;
     }
   else
     {
@@ -1624,8 +1648,10 @@ x_command (char *exp, int from_tty)
   struct format_data fmt;
   struct value *val;
 
-  fmt.format = last_format ? last_format : 'x';
-  fmt.size = last_size;
+  current_printcmd_info &ci = get_current_printcmd_info ();
+
+  fmt.format = ci.last_format ? ci.last_format : 'x';
+  fmt.size = ci.last_size;
   fmt.count = 1;
   fmt.raw = 0;
 
@@ -1633,7 +1659,7 @@ x_command (char *exp, int from_tty)
     {
       const char *tmp = exp + 1;
 
-      fmt = decode_format (&tmp, last_format, last_size);
+      fmt = decode_format (&tmp, ci.last_format, ci.last_size);
       exp = (char *) tmp;
     }
 
@@ -1655,45 +1681,45 @@ x_command (char *exp, int from_tty)
       if (/* last_format == 'i'  && */ 
 	  TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
 	   && VALUE_LVAL (val) == lval_memory)
-	next_address = value_address (val);
+	ci.next_address = value_address (val);
       else
-	next_address = value_as_address (val);
+	ci.next_address = value_as_address (val);
 
-      next_gdbarch = expr->gdbarch;
+      ci.next_gdbarch = expr->gdbarch;
     }
 
-  if (!next_gdbarch)
+  if (!ci.next_gdbarch)
     error_no_arg (_("starting display address"));
 
-  do_examine (fmt, next_gdbarch, next_address);
+  do_examine (fmt, ci.next_gdbarch, ci.next_address);
 
   /* If the examine succeeds, we remember its size and format for next
      time.  Set last_size to 'b' for strings.  */
   if (fmt.format == 's')
-    last_size = 'b';
+    ci.last_size = 'b';
   else
-    last_size = fmt.size;
-  last_format = fmt.format;
+    ci.last_size = fmt.size;
+  ci.last_format = fmt.format;
 
   /* Set a couple of internal variables if appropriate.  */
-  if (last_examine_value)
+  if (ci.last_examine_value)
     {
       /* Make last address examined available to the user as $_.  Use
          the correct pointer type.  */
       struct type *pointer_type
-	= lookup_pointer_type (value_type (last_examine_value));
+	= lookup_pointer_type (value_type (ci.last_examine_value));
       set_internalvar (lookup_internalvar ("_"),
 		       value_from_pointer (pointer_type,
-					   last_examine_address));
+					   ci.last_examine_address));
 
       /* Make contents of last address examined available to the user
 	 as $__.  If the last value has not been fetched from memory
 	 then don't fetch it now; instead mark it by voiding the $__
 	 variable.  */
-      if (value_lazy (last_examine_value))
+      if (value_lazy (ci.last_examine_value))
 	clear_internalvar (lookup_internalvar ("__"));
       else
-	set_internalvar (lookup_internalvar ("__"), last_examine_value);
+	set_internalvar (lookup_internalvar ("__"), ci.last_examine_value);
     }
 }
 
diff --git a/gdb/source.c b/gdb/source.c
index aa672fd..61a3634 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -44,6 +44,7 @@
 #include "readline/readline.h"
 #include "common/enum-flags.h"
 #include <algorithm>
+#include "top.h"
 
 #define OPEN_MODE (O_RDONLY | O_BINARY)
 #define FDOPEN_MODE FOPEN_RB
@@ -76,15 +77,45 @@ struct substitute_path_rule
 
 static struct substitute_path_rule *substitute_path_rules = NULL;
 
-/* Symtab of default file for listing lines of.  */
+struct current_source_info
+{
+  /* Symtab of default file for listing lines of.  */
+  symtab *current_source_symtab = NULL;
+
+  /* Default next line to list.  */
+  int current_source_line = 0;
 
-static struct symtab *current_source_symtab;
+  program_space *current_source_pspace = NULL;
 
-/* Default next line to list.  */
+  /* Line number of last line printed.  Default for various commands.
+     source_line is usually, but not always, the same as this.  */
+  int last_line_listed;
 
-static int current_source_line;
+  /* First line number listed by last listing command.  If 0, then no
+     source lines have yet been listed since the last time the current
+     source line was changed.  */
+  int first_line_listed;
 
-static struct program_space *current_source_pspace;
+  /* Saves the name of the last source file visited and a possible
+     error code.  Used to prevent repeating annoying "No such file or
+     directories" msgs.  */
+  struct symtab *last_source_visited = NULL;
+  int last_source_error = 0;
+};
+
+static current_source_info &
+get_current_source_info ()
+{
+  if (current_ui->curr_source_info == NULL)
+    current_ui->curr_source_info = new current_source_info ();
+  return *current_ui->curr_source_info;
+}
+
+void
+delete_current_source_info (struct ui *ui)
+{
+  delete ui->curr_source_info;
+}
 
 /* Default number of lines to print with commands like "list".
    This is based on guessing how many long (i.e. more than chars_per_line
@@ -123,23 +154,8 @@ show_filename_display_string (struct ui_file *file, int from_tty,
 {
   fprintf_filtered (file, _("Filenames are displayed as \"%s\".\n"), value);
 }
- 
-/* Line number of last line printed.  Default for various commands.
-   current_source_line is usually, but not always, the same as this.  */
-
-static int last_line_listed;
-
-/* First line number listed by last listing command.  If 0, then no
-   source lines have yet been listed since the last time the current
-   source line was changed.  */
-
-static int first_line_listed;
 
-/* Saves the name of the last source file visited and a possible error code.
-   Used to prevent repeating annoying "No such file or directories" msgs.  */
 
-static struct symtab *last_source_visited = NULL;
-static int last_source_error = 0;
 
 /* Return the first line listed by print_source_lines.
    Used by command interpreters to request listing from
@@ -148,7 +164,9 @@ static int last_source_error = 0;
 int
 get_first_line_listed (void)
 {
-  return first_line_listed;
+  current_source_info &si = get_current_source_info ();
+
+  return si.first_line_listed;
 }
 
 /* Clear line listed range.  This makes the next "list" center the
@@ -157,8 +175,10 @@ get_first_line_listed (void)
 static void
 clear_lines_listed_range (void)
 {
-  first_line_listed = 0;
-  last_line_listed = 0;
+  current_source_info &si = get_current_source_info ();
+
+  si.first_line_listed = 0;
+  si.last_line_listed = 0;
 }
 
 /* Return the default number of lines to print with commands like the
@@ -180,12 +200,14 @@ get_current_source_symtab_and_line (void)
 {
   symtab_and_line cursal;
 
-  cursal.pspace = current_source_pspace;
-  cursal.symtab = current_source_symtab;
-  cursal.line = current_source_line;
+  current_source_info &si = get_current_source_info ();
+
+  cursal.pspace = si.current_source_pspace;
+  cursal.symtab = si.current_source_symtab;
+  cursal.line = si.current_source_line;
   cursal.pc = 0;
   cursal.end = 0;
-  
+
   return cursal;
 }
 
@@ -203,8 +225,9 @@ set_default_source_symtab_and_line (void)
   if (!have_full_symbols () && !have_partial_symbols ())
     error (_("No symbol table is loaded.  Use the \"file\" command."));
 
+  current_source_info &si = get_current_source_info ();
   /* Pull in a current source symtab if necessary.  */
-  if (current_source_symtab == 0)
+  if (si.current_source_symtab == NULL)
     select_source_symtab (0);
 }
 
@@ -218,15 +241,17 @@ set_current_source_symtab_and_line (const symtab_and_line &sal)
 {
   symtab_and_line cursal;
 
-  cursal.pspace = current_source_pspace;
-  cursal.symtab = current_source_symtab;
-  cursal.line = current_source_line;
+  current_source_info &si = get_current_source_info ();
+
+  cursal.pspace = si.current_source_pspace;
+  cursal.symtab = si.current_source_symtab;
+  cursal.line = si.current_source_line;
   cursal.pc = 0;
   cursal.end = 0;
 
-  current_source_pspace = sal.pspace;
-  current_source_symtab = sal.symtab;
-  current_source_line = sal.line;
+  si.current_source_pspace = sal.pspace;
+  si.current_source_symtab = sal.symtab;
+  si.current_source_line = sal.line;
 
   /* Force the next "list" to center around the current line.  */
   clear_lines_listed_range ();
@@ -239,8 +264,10 @@ set_current_source_symtab_and_line (const symtab_and_line &sal)
 void
 clear_current_source_symtab_and_line (void)
 {
-  current_source_symtab = 0;
-  current_source_line = 0;
+  current_source_info &si = get_current_source_info ();
+
+  si.current_source_symtab = NULL;
+  si.current_source_line = 0;
 }
 
 /* Set the source file default for the "list" command to be S.
@@ -257,15 +284,17 @@ select_source_symtab (struct symtab *s)
   struct objfile *ofp;
   struct compunit_symtab *cu;
 
+  current_source_info &si = get_current_source_info ();
+
   if (s)
     {
-      current_source_symtab = s;
-      current_source_line = 1;
-      current_source_pspace = SYMTAB_PSPACE (s);
+      si.current_source_symtab = s;
+      si.current_source_line = 1;
+      si.current_source_pspace = SYMTAB_PSPACE (s);
       return;
     }
 
-  if (current_source_symtab)
+  if (si.current_source_symtab != NULL)
     return;
 
   /* Make the default place to list be the function `main'
@@ -276,17 +305,17 @@ select_source_symtab (struct symtab *s)
 	= decode_line_with_current_source (main_name (),
 					   DECODE_LINE_FUNFIRSTLINE);
       const symtab_and_line &sal = sals[0];
-      current_source_pspace = sal.pspace;
-      current_source_symtab = sal.symtab;
-      current_source_line = std::max (sal.line - (lines_to_list - 1), 1);
-      if (current_source_symtab)
+      si.current_source_pspace = sal.pspace;
+      si.current_source_symtab = sal.symtab;
+      si.current_source_line = std::max (sal.line - (lines_to_list - 1), 1);
+      if (si.current_source_symtab != NULL)
 	return;
     }
 
   /* Alright; find the last file in the symtab list (ignoring .h's
      and namespace symtabs).  */
 
-  current_source_line = 1;
+  si.current_source_line = 1;
 
   ALL_FILETABS (ofp, cu, s)
     {
@@ -296,12 +325,12 @@ select_source_symtab (struct symtab *s)
       if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
 			|| strcmp (name, "<<C++-namespaces>>") == 0)))
 	{
-	  current_source_pspace = current_program_space;
-	  current_source_symtab = s;
+	  si.current_source_pspace = current_program_space;
+	  si.current_source_symtab = s;
 	}
     }
 
-  if (current_source_symtab)
+  if (si.current_source_symtab != NULL)
     return;
 
   ALL_OBJFILES (ofp)
@@ -309,9 +338,9 @@ select_source_symtab (struct symtab *s)
     if (ofp->sf)
       s = ofp->sf->qf->find_last_source_symtab (ofp);
     if (s)
-      current_source_symtab = s;
+      si.current_source_symtab = s;
   }
-  if (current_source_symtab)
+  if (si.current_source_symtab != NULL)
     return;
 
   error (_("Can't find a default source file"));
@@ -403,7 +432,12 @@ forget_cached_source_info (void)
       forget_cached_source_info_for_objfile (objfile);
     }
 
-  last_source_visited = NULL;
+  struct ui *ui;
+  ALL_UIS (ui)
+    {
+      if (ui->curr_source_info != NULL)
+	ui->curr_source_info->last_source_visited = NULL;
+    }
 }
 
 void
@@ -645,7 +679,8 @@ add_path (char *dirname, char **which_path, int parse_separators)
 static void
 info_source_command (char *ignore, int from_tty)
 {
-  struct symtab *s = current_source_symtab;
+  current_source_info &si = get_current_source_info ();
+  struct symtab *s = si.current_source_symtab;
   struct compunit_symtab *cust;
 
   if (!s)
@@ -1312,8 +1347,9 @@ identify_source_line (struct symtab *s, int line, int mid_statement,
   annotate_source (s->fullname, line, s->line_charpos[line - 1],
 		   mid_statement, get_objfile_arch (SYMTAB_OBJFILE (s)), pc);
 
-  current_source_line = line;
-  current_source_symtab = s;
+  current_source_info &si = get_current_source_info ();
+  si.current_source_line = line;
+  si.current_source_symtab = s;
   clear_lines_listed_range ();
   return 1;
 }
@@ -1333,36 +1369,37 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
   struct ui_out *uiout = current_uiout;
 
   /* Regardless of whether we can open the file, set current_source_symtab.  */
-  current_source_symtab = s;
-  current_source_line = line;
-  first_line_listed = line;
+  current_source_info &si = get_current_source_info ();
+  si.current_source_symtab = s;
+  si.current_source_line = line;
+  si.first_line_listed = line;
 
   /* If printing of source lines is disabled, just print file and line
      number.  */
   if (uiout->test_flags (ui_source_list))
     {
       /* Only prints "No such file or directory" once.  */
-      if ((s != last_source_visited) || (!last_source_error))
+      if ((s != si.last_source_visited) || (!si.last_source_error))
 	{
-	  last_source_visited = s;
+	  si.last_source_visited = s;
 	  desc = open_source_file (s);
 	}
       else
 	{
-	  desc = last_source_error;
+	  desc = si.last_source_error;
 	  flags |= PRINT_SOURCE_LINES_NOERROR;
 	}
     }
   else
     {
-      desc = last_source_error;
+      desc = si.last_source_error;
       flags |= PRINT_SOURCE_LINES_NOERROR;
       noprint = 1;
     }
 
   if (desc < 0 || noprint)
     {
-      last_source_error = desc;
+      si.last_source_error = desc;
 
       if (!(flags & PRINT_SOURCE_LINES_NOERROR))
 	{
@@ -1404,7 +1441,7 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
       return;
     }
 
-  last_source_error = 0;
+  si.last_source_error = 0;
 
   if (s->line_charpos == 0)
     find_source_lines (s, desc);
@@ -1432,13 +1469,13 @@ print_source_lines_base (struct symtab *s, int line, int stopline,
       c = fgetc (stream.get ());
       if (c == EOF)
 	break;
-      last_line_listed = current_source_line;
+      si.last_line_listed = si.current_source_line;
       if (flags & PRINT_SOURCE_LINES_FILENAME)
         {
           uiout->text (symtab_to_filename_for_display (s));
           uiout->text (":");
         }
-      xsnprintf (buf, sizeof (buf), "%d\t", current_source_line++);
+      xsnprintf (buf, sizeof (buf), "%d\t", si.current_source_line++);
       uiout->text (buf);
       do
 	{
@@ -1492,14 +1529,16 @@ info_line_command (char *arg, int from_tty)
   symtab_and_line curr_sal;
   gdb::array_view<symtab_and_line> sals;
 
+  current_source_info &si = get_current_source_info ();
+
   if (arg == 0)
     {
-      curr_sal.symtab = current_source_symtab;
+      curr_sal.symtab = si.current_source_symtab;
       curr_sal.pspace = current_program_space;
-      if (last_line_listed != 0)
-	curr_sal.line = last_line_listed;
+      if (si.last_line_listed != 0)
+	curr_sal.line = si.last_line_listed;
       else
-	curr_sal.line = current_source_line;
+	curr_sal.line = si.current_source_line;
 
       sals = curr_sal;
     }
@@ -1572,7 +1611,7 @@ info_line_command (char *arg, int from_tty)
 	  set_next_address (gdbarch, start_pc);
 
 	  /* Repeating "info line" should do the following line.  */
-	  last_line_listed = sal.line + 1;
+	  si.last_line_listed = sal.line + 1;
 
 	  /* If this is the only line, show the source code.  If it could
 	     not find the file, don't do anything special.  */
@@ -1599,28 +1638,30 @@ forward_search_command (char *regex, int from_tty)
   char *msg;
   struct cleanup *cleanups;
 
-  line = last_line_listed + 1;
+  current_source_info &si = get_current_source_info ();
+
+  line = si.last_line_listed + 1;
 
   msg = (char *) re_comp (regex);
   if (msg)
     error (("%s"), msg);
 
-  if (current_source_symtab == 0)
+  if (si.current_source_symtab == 0)
     select_source_symtab (0);
 
-  desc = open_source_file (current_source_symtab);
+  desc = open_source_file (si.current_source_symtab);
   if (desc < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
   cleanups = make_cleanup_close (desc);
 
-  if (current_source_symtab->line_charpos == 0)
-    find_source_lines (current_source_symtab, desc);
+  if (si.current_source_symtab->line_charpos == 0)
+    find_source_lines (si.current_source_symtab, desc);
 
-  if (line < 1 || line > current_source_symtab->nlines)
+  if (line < 1 || line > si.current_source_symtab->nlines)
     error (_("Expression not found"));
 
-  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+  if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0)
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
 
   discard_cleanups (cleanups);
   gdb_file_up stream (fdopen (desc, FDOPEN_MODE));
@@ -1664,9 +1705,9 @@ forward_search_command (char *regex, int from_tty)
       if (re_exec (buf) > 0)
 	{
 	  /* Match!  */
-	  print_source_lines (current_source_symtab, line, line + 1, 0);
+	  print_source_lines (si.current_source_symtab, line, line + 1, 0);
 	  set_internalvar_integer (lookup_internalvar ("_"), line);
-	  current_source_line = std::max (line - lines_to_list / 2, 1);
+	  si.current_source_line = std::max (line - lines_to_list / 2, 1);
 	  return;
 	}
       line++;
@@ -1684,28 +1725,30 @@ reverse_search_command (char *regex, int from_tty)
   char *msg;
   struct cleanup *cleanups;
 
-  line = last_line_listed - 1;
+  current_source_info &si = get_current_source_info ();
+
+  line = si.last_line_listed - 1;
 
   msg = (char *) re_comp (regex);
   if (msg)
     error (("%s"), msg);
 
-  if (current_source_symtab == 0)
+  if (si.current_source_symtab == 0)
     select_source_symtab (0);
 
-  desc = open_source_file (current_source_symtab);
+  desc = open_source_file (si.current_source_symtab);
   if (desc < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
   cleanups = make_cleanup_close (desc);
 
-  if (current_source_symtab->line_charpos == 0)
-    find_source_lines (current_source_symtab, desc);
+  if (si.current_source_symtab->line_charpos == 0)
+    find_source_lines (si.current_source_symtab, desc);
 
-  if (line < 1 || line > current_source_symtab->nlines)
+  if (line < 1 || line > si.current_source_symtab->nlines)
     error (_("Expression not found"));
 
-  if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
-    perror_with_name (symtab_to_filename_for_display (current_source_symtab));
+  if (lseek (desc, si.current_source_symtab->line_charpos[line - 1], 0) < 0)
+    perror_with_name (symtab_to_filename_for_display (si.current_source_symtab));
 
   discard_cleanups (cleanups);
   gdb_file_up stream (fdopen (desc, FDOPEN_MODE));
@@ -1738,18 +1781,18 @@ reverse_search_command (char *regex, int from_tty)
       if (re_exec (buf) > 0)
 	{
 	  /* Match!  */
-	  print_source_lines (current_source_symtab, line, line + 1, 0);
+	  print_source_lines (si.current_source_symtab, line, line + 1, 0);
 	  set_internalvar_integer (lookup_internalvar ("_"), line);
-	  current_source_line = std::max (line - lines_to_list / 2, 1);
+	  si.current_source_line = std::max (line - lines_to_list / 2, 1);
 	  return;
 	}
       line--;
       if (fseek (stream.get (),
-		 current_source_symtab->line_charpos[line - 1], 0) < 0)
+		 si.current_source_symtab->line_charpos[line - 1], 0) < 0)
 	{
 	  const char *filename;
 
-	  filename = symtab_to_filename_for_display (current_source_symtab);
+	  filename = symtab_to_filename_for_display (si.current_source_symtab);
 	  perror_with_name (filename);
 	}
     }
@@ -1974,7 +2017,6 @@ _initialize_source (void)
 {
   struct cmd_list_element *c;
 
-  current_source_symtab = 0;
   init_source_path ();
 
   /* The intention is to use POSIX Basic Regular Expressions.
diff --git a/gdb/top.c b/gdb/top.c
index f006c66..3919203 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -132,10 +132,6 @@ show_confirm (struct ui_file *file, int from_tty,
 
 char *current_directory;
 
-/* The last command line executed on the console.  Used for command
-   repetitions.  */
-char *saved_command_line;
-
 /* Nonzero if the current command is modified by "server ".  This
    affects things like recording into the command history, commands
    repeating on RETURN, etc.  This is so a user interface (emacs, GUI,
@@ -251,6 +247,7 @@ static int highest_ui_num;
 ui::ui (FILE *instream_, FILE *outstream_, FILE *errstream_)
   : next (nullptr),
     num (++highest_ui_num),
+    saved_command_line (xstrdup ("")),
     call_readline (nullptr),
     input_handler (nullptr),
     command_editing (0),
@@ -301,6 +298,10 @@ ui::~ui ()
   else
     ui_list = next;
 
+  delete_current_printcmd_info (this);
+  delete_current_source_info (this);
+  delete_current_top_info (this);
+
   delete m_gdb_stdin;
   delete m_gdb_stdout;
   delete m_gdb_stderr;
@@ -675,7 +676,10 @@ dont_repeat (void)
      thing read from stdin in line and don't want to delete it.  Null
      lines won't repeat here in any case.  */
   if (ui->instream == ui->stdin_stream)
-    *saved_command_line = 0;
+    {
+      xfree (ui->saved_command_line);
+      ui->saved_command_line = NULL;
+    }
 }
 
 /* Prevent dont_repeat from working, and return a cleanup that
@@ -1659,11 +1663,33 @@ dont_repeat_command (char *ignored, int from_tty)
 {
   /* Can't call dont_repeat here because we're not necessarily reading
      from stdin.  */
-  *saved_command_line = 0;
+  xfree (current_ui->saved_command_line);
+  current_ui->saved_command_line = NULL;
 }
 
 /* Functions to manipulate command line editing control variables.  */
 
+struct current_top_info
+{
+  /* Number of the history entry which we are planning to display
+     next in "show commands".  Relative to history_base.  */
+  int num = 0;
+};
+
+static current_top_info &
+get_current_top_info ()
+{
+  if (current_ui->curr_top_info == NULL)
+    current_ui->curr_top_info = new current_top_info ();
+  return *current_ui->curr_top_info;
+}
+
+void
+delete_current_top_info (struct ui *ui)
+{
+  delete ui->curr_top_info;
+}
+
 /* Number of commands to print in each call to show_commands.  */
 #define Hist_print 10
 void
@@ -1672,9 +1698,7 @@ show_commands (char *args, int from_tty)
   /* Index for history commands.  Relative to history_base.  */
   int offset;
 
-  /* Number of the history entry which we are planning to display next.
-     Relative to history_base.  */
-  static int num = 0;
+  current_top_info &ci = get_current_top_info ();
 
   /* Print out some of the commands from the command history.  */
 
@@ -1685,28 +1709,28 @@ show_commands (char *args, int from_tty)
 	;
       else
 	/* "info editing <exp>" should print around command number <exp>.  */
-	num = (parse_and_eval_long (args) - history_base) - Hist_print / 2;
+	ci.num = (parse_and_eval_long (args) - history_base) - Hist_print / 2;
     }
   /* "show commands" means print the last Hist_print commands.  */
   else
     {
-      num = history_length - Hist_print;
+      ci.num = history_length - Hist_print;
     }
 
-  if (num < 0)
-    num = 0;
+  if (ci.num < 0)
+    ci.num = 0;
 
   /* If there are at least Hist_print commands, we want to display the last
      Hist_print rather than, say, the last 6.  */
-  if (history_length - num < Hist_print)
+  if (history_length - ci.num < Hist_print)
     {
-      num = history_length - Hist_print;
-      if (num < 0)
-	num = 0;
+      ci.num = history_length - Hist_print;
+      if (ci.num < 0)
+	ci.num = 0;
     }
 
-  for (offset = num;
-       offset < num + Hist_print && offset < history_length;
+  for (offset = ci.num;
+       offset < ci.num + Hist_print && offset < history_length;
        offset++)
     {
       printf_filtered ("%5d  %s\n", history_base + offset,
@@ -1715,7 +1739,7 @@ show_commands (char *args, int from_tty)
 
   /* The next command we want to display is the next one that we haven't
      displayed yet.  */
-  num += Hist_print;
+  ci.num += Hist_print;
 
   /* If the user repeats this command with return, it should do what
      "show commands +" does.  This is unnecessary if arg is null,
diff --git a/gdb/top.h b/gdb/top.h
index ab65ddb..94822772 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -71,6 +71,10 @@ struct ui
      input until we have a whole command line.  */
   struct buffer line_buffer;
 
+  /* The last command line executed on the console.  Used for command
+     repetitions.  */
+  char *saved_command_line;
+
   /* The callback used by the event loop whenever an event is detected
      on the UI's input file descriptor.  This function incrementally
      builds a buffer where it accumulates the line read up to the
@@ -130,6 +134,15 @@ struct ui
   /* See enum prompt_state's description.  */
   enum prompt_state prompt_state;
 
+  /* Per-UI info for printcmd.c.  Initialized on demand.  */
+  struct current_printcmd_info *curr_printcmd_info = NULL;
+
+  /* Per-UI info for source.c.  Initialized on demand.  */
+  struct current_source_info *curr_source_info = NULL;
+
+  /* Per-UI info for top.c.  Initialized on demand.  */
+  struct current_top_info *curr_top_info = NULL;
+
   /* The fields below that start with "m_" are "private".  They're
      meant to be accessed through wrapper macros that make them look
      like globals.  */
@@ -217,7 +230,6 @@ extern void ui_register_input_event_handler (struct ui *ui);
 extern void ui_unregister_input_event_handler (struct ui *ui);
 
 /* From top.c.  */
-extern char *saved_command_line;
 extern int confirm;
 extern int inhibit_gdbinit;
 extern const char gdbinit[];
@@ -234,6 +246,11 @@ extern void quit_command (char *, int);
 extern void quit_cover (void);
 extern void execute_command (char *, int);
 
+/* Delete the per-UI info of UI.  */
+extern void delete_current_printcmd_info (struct ui *ui);
+extern void delete_current_source_info (struct ui *ui);
+extern void delete_current_top_info (struct ui *ui);
+
 /* If the interpreter is in sync mode (we're running a user command's
    list, running command hooks or similars), and we just ran a
    synchronous command that started the target, wait for that command
