Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / printcmd.c
index 9678a73..df44ff4 100644 (file)
@@ -1,8 +1,6 @@
 /* Print values for GNU debugger GDB.
 
-   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,7 +18,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
 #include "frame.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "target.h"
 #include "breakpoint.h"
 #include "demangle.h"
+#include "gdb-demangle.h"
 #include "valprint.h"
 #include "annotate.h"
 #include "symfile.h"           /* for overlay functions */
 #include "objfiles.h"          /* ditto */
 #include "completer.h"         /* for completion functions */
 #include "ui-out.h"
-#include "gdb_assert.h"
 #include "block.h"
 #include "disasm.h"
 #include "dfp.h"
-#include "valprint.h"
-#include "exceptions.h"
 #include "observer.h"
 #include "solist.h"
-#include "solib.h"
 #include "parser-defs.h"
 #include "charset.h"
+#include "arch-utils.h"
+#include "cli/cli-utils.h"
+#include "format.h"
+#include "source.h"
 
 #ifdef TUI
-#include "tui/tui.h"           /* For tui_active et.al.   */
-#endif
-
-#if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG)
-# define USE_PRINTF_I64 1
-# define PRINTF_HAS_LONG_LONG
-#else
-# define USE_PRINTF_I64 0
+#include "tui/tui.h"           /* For tui_active et al.   */
 #endif
 
-extern int asm_demangle;       /* Whether to demangle syms in asm printouts */
-
 struct format_data
   {
     int count;
@@ -82,8 +71,9 @@ static char last_format = 0;
 
 static char last_size = 'w';
 
-/* Default address to examine next.  */
+/* Default address to examine next, and associated architecture.  */
 
+static struct gdbarch *next_gdbarch;
 static CORE_ADDR next_address;
 
 /* Number of delay instructions following current disassembled insn.  */
@@ -107,8 +97,9 @@ static void
 show_max_symbolic_offset (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-The largest offset that will be printed in <symbol+1234> form is %s.\n"),
+  fprintf_filtered (file,
+                   _("The largest offset that will be "
+                     "printed in <symbol+1234> form is %s.\n"),
                    value);
 }
 
@@ -119,32 +110,41 @@ static void
 show_print_symbol_filename (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("\
-Printing of source filename and line number with <symbol> is %s.\n"),
+  fprintf_filtered (file, _("Printing of source filename and "
+                           "line number with <symbol> is %s.\n"),
                    value);
 }
 
 /* Number of auto-display expression currently being displayed.
-   So that we can disable it if we get an error or a signal within it.
+   So that we can disable it if we get a signal within it.
    -1 when not doing one.  */
 
-int current_display_number;
+static int current_display_number;
 
 struct display
   {
     /* Chain link to next auto-display item.  */
     struct display *next;
+
     /* The expression as the user typed it.  */
     char *exp_string;
+
     /* Expression to be evaluated and displayed.  */
     struct expression *exp;
+
     /* Item number of this auto-display item.  */
     int number;
+
     /* Display format specified.  */
     struct format_data format;
-    /* Innermost block required by this expression when evaluated */
-    struct block *block;
-    /* Status of this display (enabled or disabled) */
+
+    /* Program space associated with `block'.  */
+    struct program_space *pspace;
+
+    /* Innermost block required by this expression when evaluated.  */
+    const struct block *block;
+
+    /* Status of this display (enabled or disabled).  */
     int enabled_p;
   };
 
@@ -155,13 +155,23 @@ static struct display *display_chain;
 
 static int display_number;
 
-/* Prototypes for exported functions. */
+/* Walk the following statement or block through all displays.
+   ALL_DISPLAYS_SAFE does so even if the statement deletes the current
+   display.  */
+
+#define ALL_DISPLAYS(B)                                \
+  for (B = display_chain; B; B = B->next)
+
+#define ALL_DISPLAYS_SAFE(B,TMP)               \
+  for (B = display_chain;                      \
+       B ? (TMP = B->next, 1): 0;              \
+       B = TMP)
 
-void output_command (char *, int);
+/* Prototypes for exported functions.  */
 
 void _initialize_printcmd (void);
 
-/* Prototypes for local functions. */
+/* Prototypes for local functions.  */
 
 static void do_one_display (struct display *);
 \f
@@ -177,10 +187,10 @@ static void do_one_display (struct display *);
    past the specification and past all whitespace following it.  */
 
 static struct format_data
-decode_format (char **string_ptr, int oformat, int osize)
+decode_format (const char **string_ptr, int oformat, int osize)
 {
   struct format_data val;
-  char *p = *string_ptr;
+  const char *p = *string_ptr;
 
   val.format = '?';
   val.size = '?';
@@ -231,18 +241,10 @@ decode_format (char **string_ptr, int oformat, int osize)
     switch (val.format)
       {
       case 'a':
-      case 's':
-       /* Pick the appropriate size for an address.  */
-       if (gdbarch_ptr_bit (current_gdbarch) == 64)
-         val.size = osize ? 'g' : osize;
-       else if (gdbarch_ptr_bit (current_gdbarch) == 32)
-         val.size = osize ? 'w' : osize;
-       else if (gdbarch_ptr_bit (current_gdbarch) == 16)
-         val.size = osize ? 'h' : osize;
-       else
-         /* Bad value for gdbarch_ptr_bit.  */
-         internal_error (__FILE__, __LINE__,
-                         _("failed internal consistency check"));
+       /* Pick the appropriate size for an address.  This is deferred
+          until do_examine when we know the actual architecture to use.
+          A special size value of 'a' is used to indicate this case.  */
+       val.size = osize ? 'a' : osize;
        break;
       case 'f':
        /* Floating point has to be word or giantword.  */
@@ -257,6 +259,12 @@ decode_format (char **string_ptr, int oformat, int osize)
        /* Characters default to one byte.  */
        val.size = osize ? 'b' : osize;
        break;
+      case 's':
+       /* Display strings with byte size chars unless explicitly
+          specified.  */
+       val.size = '\0';
+       break;
+
       default:
        /* The default is the size most recently specified.  */
        val.size = osize;
@@ -289,10 +297,11 @@ print_formatted (struct value *val, int size,
        case 's':
          {
            struct type *elttype = value_type (val);
+
            next_address = (value_address (val)
-                           + val_print_string (elttype,
+                           + val_print_string (elttype, NULL,
                                                value_address (val), -1,
-                                               stream, options));
+                                               stream, options) * len);
          }
          return;
 
@@ -300,7 +309,8 @@ print_formatted (struct value *val, int size,
          /* We often wrap here if there are long symbolic names.  */
          wrap_here ("    ");
          next_address = (value_address (val)
-                         + gdb_print_insn (value_address (val), stream,
+                         + gdb_print_insn (get_type_arch (type),
+                                           value_address (val), stream,
                                            &branch_delay_insns));
          return;
        }
@@ -315,58 +325,49 @@ print_formatted (struct value *val, int size,
       || TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
     value_print (val, stream, options);
   else
-    /* User specified format, so don't look to the the type to
-       tell us what to do.  */
-    print_scalar_formatted (value_contents (val), type,
-                           options, size, stream);
+    /* User specified format, so don't look to the type to tell us
+       what to do.  */
+    val_print_scalar_formatted (type,
+                               value_contents_for_printing (val),
+                               value_embedded_offset (val),
+                               val,
+                               options, size, stream);
 }
 
 /* Return builtin floating point type of same length as TYPE.
    If no such type is found, return TYPE itself.  */
 static struct type *
-float_type_from_length (struct gdbarch *gdbarch, struct type *type)
+float_type_from_length (struct type *type)
 {
+  struct gdbarch *gdbarch = get_type_arch (type);
   const struct builtin_type *builtin = builtin_type (gdbarch);
-  unsigned int len = TYPE_LENGTH (type);
 
-  if (len == TYPE_LENGTH (builtin->builtin_float))
+  if (TYPE_LENGTH (type) == TYPE_LENGTH (builtin->builtin_float))
     type = builtin->builtin_float;
-  else if (len == TYPE_LENGTH (builtin->builtin_double))
+  else if (TYPE_LENGTH (type) == TYPE_LENGTH (builtin->builtin_double))
     type = builtin->builtin_double;
-  else if (len == TYPE_LENGTH (builtin->builtin_long_double))
+  else if (TYPE_LENGTH (type) == TYPE_LENGTH (builtin->builtin_long_double))
     type = builtin->builtin_long_double;
 
   return type;
 }
 
 /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
-   according to OPTIONS and SIZE on STREAM.
-   Formats s and i are not supported at this level.
-
-   This is how the elements of an array or structure are printed
-   with a format.  */
+   according to OPTIONS and SIZE on STREAM.  Formats s and i are not
+   supported at this level.  */
 
 void
 print_scalar_formatted (const void *valaddr, struct type *type,
                        const struct value_print_options *options,
                        int size, struct ui_file *stream)
 {
+  struct gdbarch *gdbarch = get_type_arch (type);
   LONGEST val_long = 0;
   unsigned int len = TYPE_LENGTH (type);
-  enum bfd_endian byte_order = gdbarch_byte_order (current_gdbarch);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
-  /* If we get here with a string format, try again without it.  Go
-     all the way back to the language printers, which may call us
-     again.  */
-  if (options->format == 's')
-    {
-      struct value_print_options opts = *options;
-      opts.format = 0;
-      opts.deref_ref = 0;
-      val_print (type, valaddr, 0, 0, stream, 0, &opts,
-                current_language);
-      return;
-    }
+  /* String printing should go through val_print_scalar_formatted.  */
+  gdb_assert (options->format != 's');
 
   if (len > sizeof(LONGEST) &&
       (TYPE_CODE (type) == TYPE_CODE_INT
@@ -402,12 +403,12 @@ print_scalar_formatted (const void *valaddr, struct type *type,
      same, then at this point, the value's length (in target bytes) is
      gdbarch_addr_bit/TARGET_CHAR_BIT, not TYPE_LENGTH (type).  */
   if (TYPE_CODE (type) == TYPE_CODE_PTR)
-    len = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+    len = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT;
 
   /* If we are printing it as unsigned, truncate it in case it is actually
      a negative signed value (e.g. "print/u (short)-1" should print 65535
      (if shorts are 16 bits) instead of 4294967295).  */
-  if (options->format != 'd')
+  if (options->format != 'd' || TYPE_UNSIGNED (type))
     {
       if (len < sizeof (LONGEST))
        val_long &= ((LONGEST) 1 << HOST_CHAR_BIT * len) - 1;
@@ -453,26 +454,27 @@ print_scalar_formatted (const void *valaddr, struct type *type,
     case 'a':
       {
        CORE_ADDR addr = unpack_pointer (type, valaddr);
-       print_address (addr, stream);
+
+       print_address (gdbarch, addr, stream);
       }
       break;
 
     case 'c':
       {
        struct value_print_options opts = *options;
+
        opts.format = 0;
        if (TYPE_UNSIGNED (type))
-         value_print (value_from_longest (builtin_type_true_unsigned_char,
-                                          val_long),
-                      stream, &opts);
-       else
-         value_print (value_from_longest (builtin_type_true_char, val_long),
-                      stream, &opts);
+         type = builtin_type (gdbarch)->builtin_true_unsigned_char;
+       else
+         type = builtin_type (gdbarch)->builtin_true_char;
+
+       value_print (value_from_longest (type, val_long), stream, &opts);
       }
       break;
 
     case 'f':
-      type = float_type_from_length (current_gdbarch, type);
+      type = float_type_from_length (type);
       print_floating (valaddr, type, stream);
       break;
 
@@ -522,11 +524,15 @@ print_scalar_formatted (const void *valaddr, struct type *type,
            if (*cp == '\0')
              cp--;
          }
-       strcpy (buf, cp);
+       strncpy (buf, cp, sizeof (bits));
        fputs_filtered (buf, stream);
       }
       break;
 
+    case 'z':
+      print_hex_chars (stream, valaddr, len, byte_order);
+      break;
+
     default:
       error (_("Undefined output format \"%c\"."), options->format);
     }
@@ -540,6 +546,7 @@ 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;
 
   /* Make address available to the user as $_.  */
@@ -553,10 +560,12 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
    DO_DEMANGLE controls whether to print a symbol in its native "raw" form,
    or to interpret it as a possible C++ name and convert it back to source
    form.  However note that DO_DEMANGLE can be overridden by the specific
-   settings of the demangle and asm_demangle variables.  */
+   settings of the demangle and asm_demangle variables.  Returns
+   non-zero if anything was printed; zero otherwise.  */
 
-void
-print_address_symbolic (CORE_ADDR addr, struct ui_file *stream,
+int
+print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
+                       struct ui_file *stream,
                        int do_demangle, char *leadin)
 {
   char *name = NULL;
@@ -569,11 +578,11 @@ print_address_symbolic (CORE_ADDR addr, struct ui_file *stream,
   struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &name);
   make_cleanup (free_current_contents, &filename);
 
-  if (build_address_symbolic (addr, do_demangle, &name, &offset,
+  if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset,
                              &filename, &line, &unmapped))
     {
       do_cleanups (cleanup_chain);
-      return;
+      return 0;
     }
 
   fputs_filtered (leadin, stream);
@@ -600,16 +609,18 @@ print_address_symbolic (CORE_ADDR addr, struct ui_file *stream,
     fputs_filtered (">", stream);
 
   do_cleanups (cleanup_chain);
+  return 1;
 }
 
 /* Given an address ADDR return all the elements needed to print the
-   address in a symbolic form. NAME can be mangled or not depending
+   address in a symbolic form.  NAME can be mangled or not depending
    on DO_DEMANGLE (and also on the asm_demangle global variable,
-   manipulated via ''set print asm-demangle''). Return 0 in case of
-   success, when all the info in the OUT paramters is valid. Return 1
-   otherwise. */
+   manipulated via ''set print asm-demangle'').  Return 0 in case of
+   success, when all the info in the OUT paramters is valid.  Return 1
+   otherwise.  */
 int
-build_address_symbolic (CORE_ADDR addr,  /* IN */
+build_address_symbolic (struct gdbarch *gdbarch,
+                       CORE_ADDR addr,  /* IN */
                        int do_demangle, /* IN */
                        char **name,     /* OUT */
                        int *offset,     /* OUT */
@@ -617,11 +628,11 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
                        int *line,       /* OUT */
                        int *unmapped)   /* OUT */
 {
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
   struct symbol *symbol;
   CORE_ADDR name_location = 0;
   struct obj_section *section = NULL;
-  char *name_temp = "";
+  const char *name_temp = "";
   
   /* Let's say it is mapped (not unmapped).  */
   *unmapped = 0;
@@ -652,6 +663,13 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
 
   if (symbol)
     {
+      /* If this is a function (i.e. a code address), strip out any
+        non-address bits.  For instance, display a pointer to the
+        first instruction of a Thumb function as <function>; the
+        second instruction will be <function+2>, even though the
+        pointer is <function+3>.  This matches the ISA behavior.  */
+      addr = gdbarch_addr_bits_remove (gdbarch, addr);
+
       name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
       if (do_demangle || asm_demangle)
        name_temp = SYMBOL_PRINT_NAME (symbol);
@@ -659,21 +677,40 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
        name_temp = SYMBOL_LINKAGE_NAME (symbol);
     }
 
-  if (msymbol != NULL)
+  if (msymbol.minsym != NULL
+      && MSYMBOL_HAS_SIZE (msymbol.minsym)
+      && MSYMBOL_SIZE (msymbol.minsym) == 0
+      && MSYMBOL_TYPE (msymbol.minsym) != mst_text
+      && MSYMBOL_TYPE (msymbol.minsym) != mst_text_gnu_ifunc
+      && MSYMBOL_TYPE (msymbol.minsym) != mst_file_text)
+    msymbol.minsym = NULL;
+
+  if (msymbol.minsym != NULL)
     {
-      if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
+      if (BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
        {
+         /* If this is a function (i.e. a code address), strip out any
+            non-address bits.  For instance, display a pointer to the
+            first instruction of a Thumb function as <function>; the
+            second instruction will be <function+2>, even though the
+            pointer is <function+3>.  This matches the ISA behavior.  */
+         if (MSYMBOL_TYPE (msymbol.minsym) == mst_text
+             || MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc
+             || MSYMBOL_TYPE (msymbol.minsym) == mst_file_text
+             || MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
+           addr = gdbarch_addr_bits_remove (gdbarch, addr);
+
          /* The msymbol is closer to the address than the symbol;
             use the msymbol instead.  */
          symbol = 0;
-         name_location = SYMBOL_VALUE_ADDRESS (msymbol);
+         name_location = BMSYMBOL_VALUE_ADDRESS (msymbol);
          if (do_demangle || asm_demangle)
-           name_temp = SYMBOL_PRINT_NAME (msymbol);
+           name_temp = MSYMBOL_PRINT_NAME (msymbol.minsym);
          else
-           name_temp = SYMBOL_LINKAGE_NAME (msymbol);
+           name_temp = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
        }
     }
-  if (symbol == NULL && msymbol == NULL)
+  if (symbol == NULL && msymbol.minsym == NULL)
     return 1;
 
   /* If the nearest symbol is too far away, don't print anything symbolic.  */
@@ -699,7 +736,7 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
 
       if (sal.symtab)
        {
-         *filename = xstrdup (sal.symtab->filename);
+         *filename = xstrdup (symtab_to_filename_for_display (sal.symtab));
          *line = sal.line;
        }
     }
@@ -712,54 +749,58 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
    <SYMBOL + OFFSET> after the number.  */
 
 void
-print_address (CORE_ADDR addr, struct ui_file *stream)
+print_address (struct gdbarch *gdbarch,
+              CORE_ADDR addr, struct ui_file *stream)
 {
-  fputs_filtered (paddress (addr), stream);
-  print_address_symbolic (addr, stream, asm_demangle, " ");
+  fputs_filtered (paddress (gdbarch, addr), stream);
+  print_address_symbolic (gdbarch, addr, stream, asm_demangle, " ");
 }
 
-/* Print address ADDR symbolically on STREAM.  Parameter DEMANGLE
-   controls whether to print the symbolic name "raw" or demangled.
-   Global setting "addressprint" controls whether to print hex address
-   or not.  */
+/* Return a prefix for instruction address:
+   "=> " for current instruction, else "   ".  */
 
-void
-print_address_demangle (CORE_ADDR addr, struct ui_file *stream,
-                       int do_demangle)
+const char *
+pc_prefix (CORE_ADDR addr)
 {
-  struct value_print_options opts;
-  get_user_print_options (&opts);
-  if (addr == 0)
+  if (has_stack_frames ())
     {
-      fprintf_filtered (stream, "0");
+      struct frame_info *frame;
+      CORE_ADDR pc;
+
+      frame = get_selected_frame (NULL);
+      if (get_frame_pc_if_available (frame, &pc) && pc == addr)
+       return "=> ";
     }
-  else if (opts.addressprint)
+  return "   ";
+}
+
+/* Print address ADDR symbolically on STREAM.  Parameter DEMANGLE
+   controls whether to print the symbolic name "raw" or demangled.
+   Return non-zero if anything was printed; zero otherwise.  */
+
+int
+print_address_demangle (const struct value_print_options *opts,
+                       struct gdbarch *gdbarch, CORE_ADDR addr,
+                       struct ui_file *stream, int do_demangle)
+{
+  if (opts->addressprint)
     {
-      fputs_filtered (paddress (addr), stream);
-      print_address_symbolic (addr, stream, do_demangle, " ");
+      fputs_filtered (paddress (gdbarch, addr), stream);
+      print_address_symbolic (gdbarch, addr, stream, do_demangle, " ");
     }
   else
     {
-      print_address_symbolic (addr, stream, do_demangle, "");
+      return print_address_symbolic (gdbarch, addr, stream, do_demangle, "");
     }
+  return 1;
 }
 \f
 
-/* These are the types that $__ will get after an examine command of one
-   of these sizes.  */
-
-static struct type *examine_i_type;
-
-static struct type *examine_b_type;
-static struct type *examine_h_type;
-static struct type *examine_w_type;
-static struct type *examine_g_type;
-
 /* Examine data at address ADDR in format FMT.
    Fetch it from memory and print on gdb_stdout.  */
 
 static void
-do_examine (struct format_data fmt, CORE_ADDR addr)
+do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   char format = 0;
   char size;
@@ -772,23 +813,61 @@ do_examine (struct format_data fmt, CORE_ADDR addr)
   format = fmt.format;
   size = fmt.size;
   count = fmt.count;
+  next_gdbarch = gdbarch;
   next_address = addr;
 
-  /* String or instruction format implies fetch single bytes
-     regardless of the specified size.  */
-  if (format == 's' || format == 'i')
+  /* Instruction format implies fetch single bytes
+     regardless of the specified size.
+     The case of strings is handled in decode_format, only explicit
+     size operator are not changed to 'b'.  */
+  if (format == 'i')
     size = 'b';
 
-  if (format == 'i')
-    val_type = examine_i_type;
-  else if (size == 'b')
-    val_type = examine_b_type;
+  if (size == 'a')
+    {
+      /* Pick the appropriate size for an address.  */
+      if (gdbarch_ptr_bit (next_gdbarch) == 64)
+       size = 'g';
+      else if (gdbarch_ptr_bit (next_gdbarch) == 32)
+       size = 'w';
+      else if (gdbarch_ptr_bit (next_gdbarch) == 16)
+       size = 'h';
+      else
+       /* Bad value for gdbarch_ptr_bit.  */
+       internal_error (__FILE__, __LINE__,
+                       _("failed internal consistency check"));
+    }
+
+  if (size == 'b')
+    val_type = builtin_type (next_gdbarch)->builtin_int8;
   else if (size == 'h')
-    val_type = examine_h_type;
+    val_type = builtin_type (next_gdbarch)->builtin_int16;
   else if (size == 'w')
-    val_type = examine_w_type;
+    val_type = builtin_type (next_gdbarch)->builtin_int32;
   else if (size == 'g')
-    val_type = examine_g_type;
+    val_type = builtin_type (next_gdbarch)->builtin_int64;
+
+  if (format == 's')
+    {
+      struct type *char_type = NULL;
+
+      /* 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;
+      else if (size == 'w')
+       char_type = builtin_type (next_gdbarch)->builtin_char32;
+      if (char_type)
+        val_type = char_type;
+      else
+        {
+         if (size != '\0' && size != 'b')
+           warning (_("Unable to display strings with "
+                      "size '%c', using 'b' instead."), size);
+         size = 'b';
+         val_type = builtin_type (next_gdbarch)->builtin_int8;
+        }
+    }
 
   maxelts = 8;
   if (size == 'w')
@@ -806,7 +885,9 @@ do_examine (struct format_data fmt, CORE_ADDR addr)
   while (count > 0)
     {
       QUIT;
-      print_address (next_address, gdb_stdout);
+      if (format == 'i')
+       fputs_filtered (pc_prefix (next_address), gdb_stdout);
+      print_address (next_gdbarch, next_address, gdb_stdout);
       printf_filtered (":");
       for (i = maxelts;
           i > 0 && count > 0;
@@ -828,7 +909,7 @@ do_examine (struct format_data fmt, CORE_ADDR addr)
             the address stored in LAST_EXAMINE_VALUE.  FIXME: Should
             the disassembler be modified so that LAST_EXAMINE_VALUE
             is left with the byte sequence from the last complete
-            instruction fetched from memory? */
+            instruction fetched from memory?  */
          last_examine_value = value_at_lazy (val_type, next_address);
 
          if (last_examine_value)
@@ -863,14 +944,13 @@ validate_format (struct format_data fmt, char *cmdname)
    first argument ("/x myvar" for example, to print myvar in hex).  */
 
 static void
-print_command_1 (char *exp, int inspect, int voidprint)
+print_command_1 (const char *exp, int voidprint)
 {
   struct expression *expr;
-  struct cleanup *old_chain = 0;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   char format = 0;
   struct value *val;
   struct format_data fmt;
-  int cleanup = 0;
 
   if (exp && *exp == '/')
     {
@@ -889,10 +969,8 @@ print_command_1 (char *exp, int inspect, int voidprint)
 
   if (exp && *exp)
     {
-      struct type *type;
       expr = parse_expression (exp);
-      old_chain = make_cleanup (free_current_contents, &expr);
-      cleanup = 1;
+      make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
     }
   else
@@ -904,64 +982,49 @@ print_command_1 (char *exp, int inspect, int voidprint)
       struct value_print_options opts;
       int histindex = record_latest_value (val);
 
-      if (histindex >= 0)
-       annotate_value_history_begin (histindex, value_type (val));
-      else
-       annotate_value_begin (value_type (val));
+      annotate_value_history_begin (histindex, value_type (val));
 
-      if (inspect)
-       printf_unfiltered ("\031(gdb-makebuffer \"%s\"  %d '(\"",
-                          exp, histindex);
-      else if (histindex >= 0)
-       printf_filtered ("$%d = ", histindex);
+      printf_filtered ("$%d = ", histindex);
 
-      if (histindex >= 0)
-       annotate_value_history_value ();
+      annotate_value_history_value ();
 
       get_formatted_print_options (&opts, format);
-      opts.inspect_it = inspect;
       opts.raw = fmt.raw;
 
       print_formatted (val, fmt.size, &opts, gdb_stdout);
       printf_filtered ("\n");
 
-      if (histindex >= 0)
-       annotate_value_history_end ();
-      else
-       annotate_value_end ();
-
-      if (inspect)
-       printf_unfiltered ("\") )\030");
+      annotate_value_history_end ();
     }
 
-  if (cleanup)
-    do_cleanups (old_chain);
+  do_cleanups (old_chain);
 }
 
 static void
 print_command (char *exp, int from_tty)
 {
-  print_command_1 (exp, 0, 1);
+  print_command_1 (exp, 1);
 }
 
-/* Same as print, except in epoch, it gets its own window.  */
+/* Same as print, except it doesn't print void results.  */
 static void
-inspect_command (char *exp, int from_tty)
+call_command (char *exp, int from_tty)
 {
-  extern int epoch_interface;
-
-  print_command_1 (exp, epoch_interface, 1);
+  print_command_1 (exp, 0);
 }
 
-/* Same as print, except it doesn't print void results.  */
+/* Implementation of the "output" command.  */
+
 static void
-call_command (char *exp, int from_tty)
+output_command (char *exp, int from_tty)
 {
-  print_command_1 (exp, 0, 0);
+  output_command_const (exp, from_tty);
 }
 
+/* Like output_command, but takes a const string as argument.  */
+
 void
-output_command (char *exp, int from_tty)
+output_command_const (const char *exp, int from_tty)
 {
   struct expression *expr;
   struct cleanup *old_chain;
@@ -1006,6 +1069,23 @@ set_command (char *exp, int from_tty)
   struct expression *expr = parse_expression (exp);
   struct cleanup *old_chain =
     make_cleanup (free_current_contents, &expr);
+
+  if (expr->nelts >= 1)
+    switch (expr->elts[0].opcode)
+      {
+      case UNOP_PREINCREMENT:
+      case UNOP_POSTINCREMENT:
+      case UNOP_PREDECREMENT:
+      case UNOP_POSTDECREMENT:
+      case BINOP_ASSIGN:
+      case BINOP_ASSIGN_MODIFY:
+      case BINOP_COMMA:
+       break;
+      default:
+       warning
+         (_("Expression is not an assignment (and might have no effect)"));
+      }
+
   evaluate_expression (expr);
   do_cleanups (old_chain);
 }
@@ -1035,17 +1115,18 @@ sym_info (char *arg, int from_tty)
 
     if (obj_section_addr (osect) <= sect_addr
        && sect_addr < obj_section_endaddr (osect)
-       && (msymbol = lookup_minimal_symbol_by_pc_section (sect_addr, osect)))
+       && (msymbol
+           = lookup_minimal_symbol_by_pc_section (sect_addr, osect).minsym))
       {
        const char *obj_name, *mapped, *sec_name, *msym_name;
        char *loc_string;
        struct cleanup *old_chain;
 
        matches = 1;
-       offset = sect_addr - SYMBOL_VALUE_ADDRESS (msymbol);
+       offset = sect_addr - MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
        mapped = section_is_mapped (osect) ? _("mapped") : _("unmapped");
        sec_name = osect->the_bfd_section->name;
-       msym_name = SYMBOL_PRINT_NAME (msymbol);
+       msym_name = MSYMBOL_PRINT_NAME (msymbol);
 
        /* Don't print the offset if it is zero.
           We assume there's no need to handle i18n of "sym + offset".  */
@@ -1058,8 +1139,8 @@ sym_info (char *arg, int from_tty)
           a pagination request inside printf_filtered.  */
        old_chain = make_cleanup (xfree, loc_string);
 
-       gdb_assert (osect->objfile && osect->objfile->name);
-       obj_name = osect->objfile->name;
+       gdb_assert (osect->objfile && objfile_name (osect->objfile));
+       obj_name = objfile_name (osect->objfile);
 
        if (MULTI_OBJFILE_P ())
          if (pc_in_unmapped_range (addr, osect))
@@ -1108,21 +1189,20 @@ address_info (char *exp, int from_tty)
   struct gdbarch *gdbarch;
   int regno;
   struct symbol *sym;
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
   long val;
   struct obj_section *section;
-  CORE_ADDR load_addr;
-  int is_a_field_of_this;      /* C++: lookup_symbol sets this to nonzero
-                                  if exp is a field of `this'. */
+  CORE_ADDR load_addr, context_pc = 0;
+  struct field_of_this_result is_a_field_of_this;
 
   if (exp == 0)
     error (_("Argument required."));
 
-  sym = lookup_symbol (exp, get_selected_block (0), VAR_DOMAIN,
+  sym = lookup_symbol (exp, get_selected_block (&context_pc), VAR_DOMAIN,
                       &is_a_field_of_this);
   if (sym == NULL)
     {
-      if (is_a_field_of_this)
+      if (is_a_field_of_this.type != NULL)
        {
          printf_filtered ("Symbol \"");
          fprintf_symbol_filtered (gdb_stdout, exp,
@@ -1135,24 +1215,27 @@ address_info (char *exp, int from_tty)
          return;
        }
 
-      msymbol = lookup_minimal_symbol (exp, NULL, NULL);
+      msymbol = lookup_bound_minimal_symbol (exp);
 
-      if (msymbol != NULL)
+      if (msymbol.minsym != NULL)
        {
-         load_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+         struct objfile *objfile = msymbol.objfile;
+
+         gdbarch = get_objfile_arch (objfile);
+         load_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
 
          printf_filtered ("Symbol \"");
          fprintf_symbol_filtered (gdb_stdout, exp,
                                   current_language->la_language, DMGL_ANSI);
          printf_filtered ("\" is at ");
-         fputs_filtered (paddress (load_addr), gdb_stdout);
+         fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
          printf_filtered (" in a file compiled without debugging");
-         section = SYMBOL_OBJ_SECTION (msymbol);
+         section = MSYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
          if (section_is_overlay (section))
            {
              load_addr = overlay_unmapped_address (load_addr, section);
              printf_filtered (",\n -- loaded at ");
-             fputs_filtered (paddress (load_addr), gdb_stdout);
+             fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
              printf_filtered (" in overlay section %s",
                               section->the_bfd_section->name);
            }
@@ -1168,9 +1251,17 @@ address_info (char *exp, int from_tty)
                           current_language->la_language, DMGL_ANSI);
   printf_filtered ("\" is ");
   val = SYMBOL_VALUE (sym);
-  section = SYMBOL_OBJ_SECTION (sym);
+  section = SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sym), sym);
   gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
 
+  if (SYMBOL_COMPUTED_OPS (sym) != NULL)
+    {
+      SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc,
+                                                   gdb_stdout);
+      printf_filtered (".\n");
+      return;
+    }
+
   switch (SYMBOL_CLASS (sym))
     {
     case LOC_CONST:
@@ -1180,26 +1271,20 @@ address_info (char *exp, int from_tty)
 
     case LOC_LABEL:
       printf_filtered ("a label at address ");
-      fputs_filtered (paddress (load_addr = SYMBOL_VALUE_ADDRESS (sym)),
-                     gdb_stdout);
+      load_addr = SYMBOL_VALUE_ADDRESS (sym);
+      fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
       if (section_is_overlay (section))
        {
          load_addr = overlay_unmapped_address (load_addr, section);
          printf_filtered (",\n -- loaded at ");
-         fputs_filtered (paddress (load_addr), gdb_stdout);
+         fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
          printf_filtered (" in overlay section %s",
                           section->the_bfd_section->name);
        }
       break;
 
     case LOC_COMPUTED:
-      /* FIXME: cagney/2004-01-26: It should be possible to
-        unconditionally call the SYMBOL_COMPUTED_OPS method when available.
-        Unfortunately DWARF 2 stores the frame-base (instead of the
-        function) location in a function's symbol.  Oops!  For the
-        moment enable this when/where applicable.  */
-      SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
-      break;
+      gdb_assert_not_reached (_("LOC_COMPUTED variable missing a method"));
 
     case LOC_REGISTER:
       /* GDBARCH is the architecture associated with the objfile the symbol
@@ -1220,13 +1305,13 @@ address_info (char *exp, int from_tty)
 
     case LOC_STATIC:
       printf_filtered (_("static storage at address "));
-     fputs_filtered (paddress (load_addr = SYMBOL_VALUE_ADDRESS (sym)),
-                    gdb_stdout);
+      load_addr = SYMBOL_VALUE_ADDRESS (sym);
+      fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
       if (section_is_overlay (section))
        {
          load_addr = overlay_unmapped_address (load_addr, section);
          printf_filtered (_(",\n -- loaded at "));
-         fputs_filtered (paddress (load_addr), gdb_stdout);
+         fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
          printf_filtered (_(" in overlay section %s"),
                           section->the_bfd_section->name);
        }
@@ -1258,12 +1343,12 @@ address_info (char *exp, int from_tty)
     case LOC_BLOCK:
       printf_filtered (_("a function at address "));
       load_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
-      fputs_filtered (paddress (load_addr), gdb_stdout);
+      fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
       if (section_is_overlay (section))
        {
          load_addr = overlay_unmapped_address (load_addr, section);
          printf_filtered (_(",\n -- loaded at "));
-         fputs_filtered (paddress (load_addr), gdb_stdout);
+         fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
          printf_filtered (_(" in overlay section %s"),
                           section->the_bfd_section->name);
        }
@@ -1271,30 +1356,31 @@ address_info (char *exp, int from_tty)
 
     case LOC_UNRESOLVED:
       {
-       struct minimal_symbol *msym;
+       struct bound_minimal_symbol msym;
 
-       msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (sym), NULL, NULL);
-       if (msym == NULL)
+       msym = lookup_minimal_symbol_and_objfile (SYMBOL_LINKAGE_NAME (sym));
+       if (msym.minsym == NULL)
          printf_filtered ("unresolved");
        else
          {
-           section = SYMBOL_OBJ_SECTION (msym);
-           load_addr = SYMBOL_VALUE_ADDRESS (msym);
+           section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym);
+           load_addr = BMSYMBOL_VALUE_ADDRESS (msym);
 
            if (section
                && (section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0)
              printf_filtered (_("a thread-local variable at offset %s "
                                 "in the thread-local storage for `%s'"),
-                              paddr_nz (load_addr), section->objfile->name);
+                              paddress (gdbarch, load_addr),
+                              objfile_name (section->objfile));
            else
              {
                printf_filtered (_("static storage at address "));
-               fputs_filtered (paddress (load_addr), gdb_stdout);
+               fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
                if (section_is_overlay (section))
                  {
                    load_addr = overlay_unmapped_address (load_addr, section);
                    printf_filtered (_(",\n -- loaded at "));
-                   fputs_filtered (paddress (load_addr), gdb_stdout);
+                   fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout);
                    printf_filtered (_(" in overlay section %s"),
                                     section->the_bfd_section->name);
                  }
@@ -1330,8 +1416,10 @@ x_command (char *exp, int from_tty)
 
   if (exp && *exp == '/')
     {
-      exp++;
-      fmt = decode_format (&exp, last_format, last_size);
+      const char *tmp = exp + 1;
+
+      fmt = decode_format (&tmp, last_format, last_size);
+      exp = (char *) tmp;
     }
 
   /* If we have an expression, evaluate it and use it as the address.  */
@@ -1347,7 +1435,7 @@ x_command (char *exp, int from_tty)
       old_chain = make_cleanup (free_current_contents, &expr);
       val = evaluate_expression (expr);
       if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
-       val = value_ind (val);
+       val = coerce_ref (val);
       /* In rvalue contexts, such as this, functions are coerced into
          pointers to functions.  This makes "x/i main" work.  */
       if (/* last_format == 'i'  && */ 
@@ -1356,17 +1444,25 @@ x_command (char *exp, int from_tty)
        next_address = value_address (val);
       else
        next_address = value_as_address (val);
+
+      next_gdbarch = expr->gdbarch;
       do_cleanups (old_chain);
     }
 
-  do_examine (fmt, next_address);
+  if (!next_gdbarch)
+    error_no_arg (_("starting display address"));
+
+  do_examine (fmt, next_gdbarch, next_address);
 
   /* If the examine succeeds, we remember its size and format for next
-     time.  */
-  last_size = fmt.size;
+     time.  Set last_size to 'b' for strings.  */
+  if (fmt.format == 's')
+    last_size = 'b';
+  else
+    last_size = fmt.size;
   last_format = fmt.format;
 
-  /* Set a couple of internal variables if appropriate. */
+  /* Set a couple of internal variables if appropriate.  */
   if (last_examine_value)
     {
       /* Make last address examined available to the user as $_.  Use
@@ -1393,12 +1489,13 @@ x_command (char *exp, int from_tty)
    Specify the expression.  */
 
 static void
-display_command (char *exp, int from_tty)
+display_command (char *arg, int from_tty)
 {
   struct format_data fmt;
   struct expression *expr;
   struct display *new;
   int display_it = 1;
+  const char *exp = arg;
 
 #if defined(TUI)
   /* NOTE: cagney/2003-02-13 The `tui_active' was previously
@@ -1440,13 +1537,14 @@ display_command (char *exp, int from_tty)
       new->exp_string = xstrdup (exp);
       new->exp = expr;
       new->block = innermost_block;
+      new->pspace = current_program_space;
       new->next = display_chain;
       new->number = ++display_number;
       new->format = fmt;
       new->enabled_p = 1;
       display_chain = new;
 
-      if (from_tty && target_has_execution)
+      if (from_tty)
        do_one_display (new);
 
       dont_repeat ();
@@ -1476,89 +1574,123 @@ clear_displays (void)
     }
 }
 
-/* Delete the auto-display number NUM.  */
+/* Delete the auto-display DISPLAY.  */
 
 static void
-delete_display (int num)
+delete_display (struct display *display)
 {
-  struct display *d1, *d;
+  struct display *d;
 
-  if (!display_chain)
-    error (_("No display number %d."), num);
+  gdb_assert (display != NULL);
 
-  if (display_chain->number == num)
-    {
-      d1 = display_chain;
-      display_chain = d1->next;
-      free_display (d1);
-    }
-  else
-    for (d = display_chain;; d = d->next)
+  if (display_chain == display)
+    display_chain = display->next;
+
+  ALL_DISPLAYS (d)
+    if (d->next == display)
       {
-       if (d->next == 0)
-         error (_("No display number %d."), num);
-       if (d->next->number == num)
-         {
-           d1 = d->next;
-           d->next = d1->next;
-           free_display (d1);
-           break;
-         }
+       d->next = display->next;
+       break;
       }
+
+  free_display (display);
 }
 
-/* Delete some values from the auto-display chain.
-   Specify the element numbers.  */
+/* Call FUNCTION on each of the displays whose numbers are given in
+   ARGS.  DATA is passed unmodified to FUNCTION.  */
 
 static void
-undisplay_command (char *args, int from_tty)
+map_display_numbers (char *args,
+                    void (*function) (struct display *,
+                                      void *),
+                    void *data)
 {
-  char *p = args;
-  char *p1;
+  struct get_number_or_range_state state;
   int num;
 
-  if (args == 0)
+  if (args == NULL)
+    error_no_arg (_("one or more display numbers"));
+
+  init_number_or_range (&state, args);
+
+  while (!state.finished)
     {
-      if (query (_("Delete all auto-display expressions? ")))
-       clear_displays ();
-      dont_repeat ();
-      return;
+      const char *p = state.string;
+
+      num = get_number_or_range (&state);
+      if (num == 0)
+       warning (_("bad display number at or near '%s'"), p);
+      else
+       {
+         struct display *d, *tmp;
+
+         ALL_DISPLAYS_SAFE (d, tmp)
+           if (d->number == num)
+             break;
+         if (d == NULL)
+           printf_unfiltered (_("No display number %d.\n"), num);
+         else
+           function (d, data);
+       }
     }
+}
 
-  while (*p)
-    {
-      p1 = p;
-      while (*p1 >= '0' && *p1 <= '9')
-       p1++;
-      if (*p1 && *p1 != ' ' && *p1 != '\t')
-       error (_("Arguments must be display numbers."));
+/* Callback for map_display_numbers, that deletes a display.  */
 
-      num = atoi (p);
+static void
+do_delete_display (struct display *d, void *data)
+{
+  delete_display (d);
+}
 
-      delete_display (num);
+/* "undisplay" command.  */
 
-      p = p1;
-      while (*p == ' ' || *p == '\t')
-       p++;
+static void
+undisplay_command (char *args, int from_tty)
+{
+  if (args == NULL)
+    {
+      if (query (_("Delete all auto-display expressions? ")))
+       clear_displays ();
+      dont_repeat ();
+      return;
     }
+
+  map_display_numbers (args, do_delete_display, NULL);
   dont_repeat ();
 }
 
 /* Display a single auto-display.  
    Do nothing if the display cannot be printed in the current context,
-   or if the display is disabled. */
+   or if the display is disabled.  */
 
 static void
 do_one_display (struct display *d)
 {
+  struct cleanup *old_chain;
   int within_current_scope;
 
   if (d->enabled_p == 0)
     return;
 
+  /* The expression carries the architecture that was used at parse time.
+     This is a problem if the expression depends on architecture features
+     (e.g. register numbers), and the current architecture is now different.
+     For example, a display statement like "display/i $pc" is expected to
+     display the PC register of the current architecture, not the arch at
+     the time the display command was given.  Therefore, we re-parse the
+     expression if the current architecture has changed.  */
+  if (d->exp != NULL && d->exp->gdbarch != get_current_arch ())
+    {
+      xfree (d->exp);
+      d->exp = NULL;
+      d->block = NULL;
+    }
+
   if (d->exp == NULL)
     {
       volatile struct gdb_exception ex;
+
       TRY_CATCH (ex, RETURN_MASK_ALL)
        {
          innermost_block = NULL;
@@ -1576,12 +1708,18 @@ do_one_display (struct display *d)
     }
 
   if (d->block)
-    within_current_scope = contained_in (get_selected_block (0), d->block);
+    {
+      if (d->pspace == current_program_space)
+       within_current_scope = contained_in (get_selected_block (0), d->block);
+      else
+       within_current_scope = 0;
+    }
   else
     within_current_scope = 1;
   if (!within_current_scope)
     return;
 
+  old_chain = make_cleanup_restore_integer (&current_display_number);
   current_display_number = d->number;
 
   annotate_display_begin ();
@@ -1590,8 +1728,7 @@ do_one_display (struct display *d)
   printf_filtered (": ");
   if (d->format.size)
     {
-      CORE_ADDR addr;
-      struct value *val;
+      volatile struct gdb_exception ex;
 
       annotate_display_format ();
 
@@ -1613,18 +1750,26 @@ do_one_display (struct display *d)
       else
        printf_filtered ("  ");
 
-      val = evaluate_expression (d->exp);
-      addr = value_as_address (val);
-      if (d->format.format == 'i')
-       addr = gdbarch_addr_bits_remove (d->exp->gdbarch, addr);
-
       annotate_display_value ();
 
-      do_examine (d->format, addr);
+      TRY_CATCH (ex, RETURN_MASK_ERROR)
+        {
+         struct value *val;
+         CORE_ADDR addr;
+
+         val = evaluate_expression (d->exp);
+         addr = value_as_address (val);
+         if (d->format.format == 'i')
+           addr = gdbarch_addr_bits_remove (d->exp->gdbarch, addr);
+         do_examine (d->format, d->exp->gdbarch, addr);
+       }
+      if (ex.reason < 0)
+       fprintf_filtered (gdb_stdout, _("<error: %s>\n"), ex.message);
     }
   else
     {
       struct value_print_options opts;
+      volatile struct gdb_exception ex;
 
       annotate_display_format ();
 
@@ -1642,15 +1787,23 @@ do_one_display (struct display *d)
 
       get_formatted_print_options (&opts, d->format.format);
       opts.raw = d->format.raw;
-      print_formatted (evaluate_expression (d->exp),
-                      d->format.size, &opts, gdb_stdout);
+
+      TRY_CATCH (ex, RETURN_MASK_ERROR)
+        {
+         struct value *val;
+
+         val = evaluate_expression (d->exp);
+         print_formatted (val, d->format.size, &opts, gdb_stdout);
+       }
+      if (ex.reason < 0)
+       fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
       printf_filtered ("\n");
     }
 
   annotate_display_end ();
 
   gdb_flush (gdb_stdout);
-  current_display_number = -1;
+  do_cleanups (old_chain);
 }
 
 /* Display all of the values on the auto-display chain which can be
@@ -1688,8 +1841,9 @@ disable_current_display (void)
   if (current_display_number >= 0)
     {
       disable_display (current_display_number);
-      fprintf_unfiltered (gdb_stderr, _("\
-Disabling display %d to avoid infinite recursion.\n"),
+      fprintf_unfiltered (gdb_stderr,
+                         _("Disabling display %d to "
+                           "avoid infinite recursion.\n"),
                          current_display_number);
     }
   current_display_number = -1;
@@ -1722,115 +1876,47 @@ Num Enb Expression\n"));
     }
 }
 
+/* Callback fo map_display_numbers, that enables or disables the
+   passed in display D.  */
+
 static void
-enable_display (char *args, int from_tty)
+do_enable_disable_display (struct display *d, void *data)
 {
-  char *p = args;
-  char *p1;
-  int num;
-  struct display *d;
-
-  if (p == 0)
-    {
-      for (d = display_chain; d; d = d->next)
-       d->enabled_p = 1;
-    }
-  else
-    while (*p)
-      {
-       p1 = p;
-       while (*p1 >= '0' && *p1 <= '9')
-         p1++;
-       if (*p1 && *p1 != ' ' && *p1 != '\t')
-         error (_("Arguments must be display numbers."));
-
-       num = atoi (p);
-
-       for (d = display_chain; d; d = d->next)
-         if (d->number == num)
-           {
-             d->enabled_p = 1;
-             goto win;
-           }
-       printf_unfiltered (_("No display number %d.\n"), num);
-      win:
-       p = p1;
-       while (*p == ' ' || *p == '\t')
-         p++;
-      }
+  d->enabled_p = *(int *) data;
 }
 
+/* Implamentation of both the "disable display" and "enable display"
+   commands.  ENABLE decides what to do.  */
+
 static void
-disable_display_command (char *args, int from_tty)
+enable_disable_display_command (char *args, int from_tty, int enable)
 {
-  char *p = args;
-  char *p1;
-  struct display *d;
-
-  if (p == 0)
+  if (args == NULL)
     {
-      for (d = display_chain; d; d = d->next)
-       d->enabled_p = 0;
-    }
-  else
-    while (*p)
-      {
-       p1 = p;
-       while (*p1 >= '0' && *p1 <= '9')
-         p1++;
-       if (*p1 && *p1 != ' ' && *p1 != '\t')
-         error (_("Arguments must be display numbers."));
+      struct display *d;
 
-       disable_display (atoi (p));
+      ALL_DISPLAYS (d)
+       d->enabled_p = enable;
+      return;
+    }
 
-       p = p1;
-       while (*p == ' ' || *p == '\t')
-         p++;
-      }
+  map_display_numbers (args, do_enable_disable_display, &enable);
 }
 
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
-   is unloaded), otherwise return 0.  */
+/* The "enable display" command.  */
 
-static int
-display_uses_solib_p (const struct display *d,
-                     const struct so_list *solib)
+static void
+enable_display_command (char *args, int from_tty)
 {
-  int endpos;
-  struct expression *const exp = d->exp;
-  const union exp_element *const elts = exp->elts;
-
-  if (d->block != NULL
-      && solib_contains_address_p (solib, d->block->startaddr))
-    return 1;
-
-  for (endpos = exp->nelts; endpos > 0; )
-    {
-      int i, args, oplen = 0;
-
-      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
-                                                       &oplen, &args);
-      gdb_assert (oplen > 0);
-
-      i = endpos - oplen;
-      if (elts[i].opcode == OP_VAR_VALUE)
-       {
-         const struct block *const block = elts[i + 1].block;
-         const struct symbol *const symbol = elts[i + 2].symbol;
-         const struct obj_section *const section =
-           SYMBOL_OBJ_SECTION (symbol);
+  enable_disable_display_command (args, from_tty, 1);
+}
 
-         if (block != NULL
-             && solib_contains_address_p (solib, block->startaddr))
-           return 1;
+/* The "disable display" command.  */
 
-         if (section && section->objfile == solib->objfile)
-           return 1;
-       }
-      endpos -= oplen;
-    }
-
-  return 0;
+static void
+disable_display_command (char *args, int from_tty)
+{
+  enable_disable_display_command (args, from_tty, 0);
 }
 
 /* display_chain items point to blocks and expressions.  Some expressions in
@@ -1842,19 +1928,33 @@ display_uses_solib_p (const struct display *d,
    an item by re-parsing .exp_string field in the new execution context.  */
 
 static void
-clear_dangling_display_expressions (struct so_list *solib)
+clear_dangling_display_expressions (struct objfile *objfile)
 {
   struct display *d;
-  struct objfile *objfile = NULL;
+  struct program_space *pspace;
 
-  for (d = display_chain; d; d = d->next)
+  /* With no symbol file we cannot have a block or expression from it.  */
+  if (objfile == NULL)
+    return;
+  pspace = objfile->pspace;
+  if (objfile->separate_debug_objfile_backlink)
     {
-      if (d->exp && display_uses_solib_p (d, solib))
-       {
-         xfree (d->exp);
-         d->exp = NULL;
-         d->block = NULL;
-       }
+      objfile = objfile->separate_debug_objfile_backlink;
+      gdb_assert (objfile->pspace == pspace);
+    }
+
+  for (d = display_chain; d != NULL; d = d->next)
+    {
+      if (d->pspace != pspace)
+       continue;
+
+      if (lookup_objfile_from_block (d->block) == objfile
+         || (d->exp && exp_uses_objfile (d->exp, objfile)))
+      {
+       xfree (d->exp);
+       d->exp = NULL;
+       d->block = NULL;
+      }
     }
 }
 \f
@@ -1863,361 +1963,332 @@ clear_dangling_display_expressions (struct so_list *solib)
    struct symbol.  NAME is the name to print; if NULL then VAR's print
    name will be used.  STREAM is the ui_file on which to print the
    value.  INDENT specifies the number of indent levels to print
-   before printing the variable name.  */
+   before printing the variable name.
+
+   This function invalidates FRAME.  */
 
 void
 print_variable_and_value (const char *name, struct symbol *var,
                          struct frame_info *frame,
                          struct ui_file *stream, int indent)
 {
-  struct value *val;
-  struct value_print_options opts;
+  volatile struct gdb_exception except;
 
   if (!name)
     name = SYMBOL_PRINT_NAME (var);
 
   fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name);
+  TRY_CATCH (except, RETURN_MASK_ERROR)
+    {
+      struct value *val;
+      struct value_print_options opts;
+
+      val = read_var_value (var, frame);
+      get_user_print_options (&opts);
+      opts.deref_ref = 1;
+      common_val_print (val, stream, indent, &opts, current_language);
 
-  val = read_var_value (var, frame);
-  get_user_print_options (&opts);
-  common_val_print (val, stream, indent, &opts, current_language);
+      /* common_val_print invalidates FRAME when a pretty printer calls inferior
+        function.  */
+      frame = NULL;
+    }
+  if (except.reason < 0)
+    fprintf_filtered(stream, "<error reading variable %s (%s)>", name,
+                    except.message);
   fprintf_filtered (stream, "\n");
 }
 
+/* Subroutine of ui_printf to simplify it.
+   Print VALUE to STREAM using FORMAT.
+   VALUE is a C-style string on the target.  */
+
 static void
-printf_command (char *arg, int from_tty)
+printf_c_string (struct ui_file *stream, const char *format,
+                struct value *value)
 {
-  char *f = NULL;
-  char *s = arg;
-  char *string = NULL;
-  struct value **val_args;
-  char *substrings;
-  char *current_substring;
-  int nargs = 0;
-  int allocated_args = 20;
-  struct cleanup *old_cleanups;
+  gdb_byte *str;
+  CORE_ADDR tem;
+  int j;
 
-  val_args = xmalloc (allocated_args * sizeof (struct value *));
-  old_cleanups = make_cleanup (free_current_contents, &val_args);
+  tem = value_as_address (value);
 
-  if (s == 0)
-    error_no_arg (_("format-control string and values to print"));
+  /* This is a %s argument.  Find the length of the string.  */
+  for (j = 0;; j++)
+    {
+      gdb_byte c;
 
-  /* Skip white space before format string */
-  while (*s == ' ' || *s == '\t')
-    s++;
+      QUIT;
+      read_memory (tem + j, &c, 1);
+      if (c == 0)
+       break;
+    }
 
-  /* A format string should follow, enveloped in double quotes.  */
-  if (*s++ != '"')
-    error (_("Bad format string, missing '\"'."));
+  /* Copy the string contents into a string inside GDB.  */
+  str = (gdb_byte *) alloca (j + 1);
+  if (j != 0)
+    read_memory (tem, str, j);
+  str[j] = 0;
 
-  /* Parse the format-control string and copy it into the string STRING,
-     processing some kinds of escape sequence.  */
+  fprintf_filtered (stream, format, (char *) str);
+}
 
-  f = string = (char *) alloca (strlen (s) + 1);
+/* Subroutine of ui_printf to simplify it.
+   Print VALUE to STREAM using FORMAT.
+   VALUE is a wide C-style string on the target.  */
 
-  while (*s != '"')
+static void
+printf_wide_c_string (struct ui_file *stream, const char *format,
+                     struct value *value)
+{
+  gdb_byte *str;
+  CORE_ADDR tem;
+  int j;
+  struct gdbarch *gdbarch = get_type_arch (value_type (value));
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  struct type *wctype = lookup_typename (current_language, gdbarch,
+                                        "wchar_t", NULL, 0);
+  int wcwidth = TYPE_LENGTH (wctype);
+  gdb_byte *buf = alloca (wcwidth);
+  struct obstack output;
+  struct cleanup *inner_cleanup;
+
+  tem = value_as_address (value);
+
+  /* This is a %s argument.  Find the length of the string.  */
+  for (j = 0;; j += wcwidth)
     {
-      int c = *s++;
-      switch (c)
-       {
-       case '\0':
-         error (_("Bad format string, non-terminated '\"'."));
+      QUIT;
+      read_memory (tem + j, buf, wcwidth);
+      if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0)
+       break;
+    }
 
-       case '\\':
-         switch (c = *s++)
-           {
-           case '\\':
-             *f++ = '\\';
-             break;
-           case 'a':
-             *f++ = '\a';
-             break;
-           case 'b':
-             *f++ = '\b';
-             break;
-           case 'f':
-             *f++ = '\f';
-             break;
-           case 'n':
-             *f++ = '\n';
-             break;
-           case 'r':
-             *f++ = '\r';
-             break;
-           case 't':
-             *f++ = '\t';
-             break;
-           case 'v':
-             *f++ = '\v';
-             break;
-           case '"':
-             *f++ = '"';
-             break;
-           default:
-             /* ??? TODO: handle other escape sequences */
-             error (_("Unrecognized escape character \\%c in format string."),
-                    c);
-           }
-         break;
+  /* Copy the string contents into a string inside GDB.  */
+  str = (gdb_byte *) alloca (j + wcwidth);
+  if (j != 0)
+    read_memory (tem, str, j);
+  memset (&str[j], 0, wcwidth);
 
-       default:
-         *f++ = c;
+  obstack_init (&output);
+  inner_cleanup = make_cleanup_obstack_free (&output);
+
+  convert_between_encodings (target_wide_charset (gdbarch),
+                            host_charset (),
+                            str, j, wcwidth,
+                            &output, translit_char);
+  obstack_grow_str0 (&output, "");
+
+  fprintf_filtered (stream, format, obstack_base (&output));
+  do_cleanups (inner_cleanup);
+}
+
+/* Subroutine of ui_printf to simplify it.
+   Print VALUE, a decimal floating point value, to STREAM using FORMAT.  */
+
+static void
+printf_decfloat (struct ui_file *stream, const char *format,
+                struct value *value)
+{
+  const gdb_byte *param_ptr = value_contents (value);
+
+#if defined (PRINTF_HAS_DECFLOAT)
+  /* If we have native support for Decimal floating
+     printing, handle it here.  */
+  fprintf_filtered (stream, format, param_ptr);
+#else
+  /* As a workaround until vasprintf has native support for DFP
+     we convert the DFP values to string and print them using
+     the %s format specifier.  */
+  const char *p;
+
+  /* Parameter data.  */
+  struct type *param_type = value_type (value);
+  struct gdbarch *gdbarch = get_type_arch (param_type);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  /* DFP output data.  */
+  struct value *dfp_value = NULL;
+  gdb_byte *dfp_ptr;
+  int dfp_len = 16;
+  gdb_byte dec[16];
+  struct type *dfp_type = NULL;
+  char decstr[MAX_DECIMAL_STRING];
+
+  /* Points to the end of the string so that we can go back
+     and check for DFP length modifiers.  */
+  p = format + strlen (format);
+
+  /* Look for the float/double format specifier.  */
+  while (*p != 'f' && *p != 'e' && *p != 'E'
+        && *p != 'g' && *p != 'G')
+    p--;
+
+  /* Search for the '%' char and extract the size and type of
+     the output decimal value based on its modifiers
+     (%Hf, %Df, %DDf).  */
+  while (*--p != '%')
+    {
+      if (*p == 'H')
+       {
+         dfp_len = 4;
+         dfp_type = builtin_type (gdbarch)->builtin_decfloat;
+       }
+      else if (*p == 'D' && *(p - 1) == 'D')
+       {
+         dfp_len = 16;
+         dfp_type = builtin_type (gdbarch)->builtin_declong;
+         p--;
+       }
+      else
+       {
+         dfp_len = 8;
+         dfp_type = builtin_type (gdbarch)->builtin_decdouble;
        }
     }
 
-  /* Skip over " and following space and comma.  */
-  s++;
-  *f++ = '\0';
-  while (*s == ' ' || *s == '\t')
-    s++;
+  /* Conversion between different DFP types.  */
+  if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
+    decimal_convert (param_ptr, TYPE_LENGTH (param_type),
+                    byte_order, dec, dfp_len, byte_order);
+  else
+    /* If this is a non-trivial conversion, just output 0.
+       A correct converted value can be displayed by explicitly
+       casting to a DFP type.  */
+    decimal_from_string (dec, dfp_len, byte_order, "0");
 
-  if (*s != ',' && *s != 0)
-    error (_("Invalid argument syntax"));
+  dfp_value = value_from_decfloat (dfp_type, dec);
 
-  if (*s == ',')
-    s++;
-  while (*s == ' ' || *s == '\t')
-    s++;
+  dfp_ptr = (gdb_byte *) value_contents (dfp_value);
 
-  /* Need extra space for the '\0's.  Doubling the size is sufficient.  */
-  substrings = alloca (strlen (string) * 2);
-  current_substring = substrings;
+  decimal_to_string (dfp_ptr, dfp_len, byte_order, decstr);
 
-  {
-    /* Now scan the string for %-specs and see what kinds of args they want.
-       argclass[I] classifies the %-specs so we can give printf_filtered
-       something of the right size.  */
+  /* Print the DFP value.  */
+  fprintf_filtered (stream, "%s", decstr);
+#endif
+}
 
-    enum argclass
-      {
-       int_arg, long_arg, long_long_arg, ptr_arg,
-       string_arg, wide_string_arg, wide_char_arg,
-       double_arg, long_double_arg, decfloat_arg
-      };
-    enum argclass *argclass;
-    enum argclass this_argclass;
-    char *last_arg;
-    int nargs_wanted;
-    int i;
+/* Subroutine of ui_printf to simplify it.
+   Print VALUE, a target pointer, to STREAM using FORMAT.  */
 
-    argclass = (enum argclass *) alloca (strlen (s) * sizeof *argclass);
-    nargs_wanted = 0;
-    f = string;
-    last_arg = string;
-    while (*f)
-      if (*f++ == '%')
+static void
+printf_pointer (struct ui_file *stream, const char *format,
+               struct value *value)
+{
+  /* We avoid the host's %p because pointers are too
+     likely to be the wrong size.  The only interesting
+     modifier for %p is a width; extract that, and then
+     handle %p as glibc would: %#x or a literal "(nil)".  */
+
+  const char *p;
+  char *fmt, *fmt_p;
+#ifdef PRINTF_HAS_LONG_LONG
+  long long val = value_as_long (value);
+#else
+  long val = value_as_long (value);
+#endif
+
+  fmt = alloca (strlen (format) + 5);
+
+  /* Copy up to the leading %.  */
+  p = format;
+  fmt_p = fmt;
+  while (*p)
+    {
+      int is_percent = (*p == '%');
+
+      *fmt_p++ = *p++;
+      if (is_percent)
        {
-         int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0;
-         int seen_space = 0, seen_plus = 0;
-         int seen_big_l = 0, seen_h = 0, seen_big_h = 0;
-         int seen_big_d = 0, seen_double_big_d = 0;
-         int bad = 0;
-
-         /* Check the validity of the format specifier, and work
-            out what argument it expects.  We only accept C89
-            format strings, with the exception of long long (which
-            we autoconf for).  */
-
-         /* Skip over "%%".  */
-         if (*f == '%')
-           {
-             f++;
-             continue;
-           }
+         if (*p == '%')
+           *fmt_p++ = *p++;
+         else
+           break;
+       }
+    }
 
-         /* The first part of a format specifier is a set of flag
-            characters.  */
-         while (strchr ("0-+ #", *f))
-           {
-             if (*f == '#')
-               seen_hash = 1;
-             else if (*f == '0')
-               seen_zero = 1;
-             else if (*f == ' ')
-               seen_space = 1;
-             else if (*f == '+')
-               seen_plus = 1;
-             f++;
-           }
+  if (val != 0)
+    *fmt_p++ = '#';
 
-         /* The next part of a format specifier is a width.  */
-         while (strchr ("0123456789", *f))
-           f++;
+  /* Copy any width.  */
+  while (*p >= '0' && *p < '9')
+    *fmt_p++ = *p++;
 
-         /* The next part of a format specifier is a precision.  */
-         if (*f == '.')
-           {
-             seen_prec = 1;
-             f++;
-             while (strchr ("0123456789", *f))
-               f++;
-           }
+  gdb_assert (*p == 'p' && *(p + 1) == '\0');
+  if (val != 0)
+    {
+#ifdef PRINTF_HAS_LONG_LONG
+      *fmt_p++ = 'l';
+#endif
+      *fmt_p++ = 'l';
+      *fmt_p++ = 'x';
+      *fmt_p++ = '\0';
+      fprintf_filtered (stream, fmt, val);
+    }
+  else
+    {
+      *fmt_p++ = 's';
+      *fmt_p++ = '\0';
+      fprintf_filtered (stream, fmt, "(nil)");
+    }
+}
 
-         /* The next part of a format specifier is a length modifier.  */
-         if (*f == 'h')
-           {
-             seen_h = 1;
-             f++;
-           }
-         else if (*f == 'l')
-           {
-             f++;
-             lcount++;
-             if (*f == 'l')
-               {
-                 f++;
-                 lcount++;
-               }
-           }
-         else if (*f == 'L')
-           {
-             seen_big_l = 1;
-             f++;
-           }
-         /* Decimal32 modifier.  */
-         else if (*f == 'H')
-           {
-             seen_big_h = 1;
-             f++;
-           }
-         /* Decimal64 and Decimal128 modifiers.  */
-         else if (*f == 'D')
-           {
-             f++;
-
-             /* Check for a Decimal128.  */
-             if (*f == 'D')
-               {
-                 f++;
-                 seen_double_big_d = 1;
-               }
-             else
-               seen_big_d = 1;
-           }
+/* printf "printf format string" ARG to STREAM.  */
 
-         switch (*f)
-           {
-           case 'u':
-             if (seen_hash)
-               bad = 1;
-             /* FALLTHROUGH */
-
-           case 'o':
-           case 'x':
-           case 'X':
-             if (seen_space || seen_plus)
-               bad = 1;
-             /* FALLTHROUGH */
-
-           case 'd':
-           case 'i':
-             if (lcount == 0)
-               this_argclass = int_arg;
-             else if (lcount == 1)
-               this_argclass = long_arg;
-             else
-               this_argclass = long_long_arg;
-
-             if (seen_big_l)
-               bad = 1;
-             break;
+static void
+ui_printf (const char *arg, struct ui_file *stream)
+{
+  struct format_piece *fpieces;
+  const char *s = arg;
+  struct value **val_args;
+  int allocated_args = 20;
+  struct cleanup *old_cleanups;
 
-           case 'c':
-             this_argclass = lcount == 0 ? int_arg : wide_char_arg;
-             if (lcount > 1 || seen_h || seen_big_l)
-               bad = 1;
-             if (seen_prec || seen_zero || seen_space || seen_plus)
-               bad = 1;
-             break;
+  val_args = xmalloc (allocated_args * sizeof (struct value *));
+  old_cleanups = make_cleanup (free_current_contents, &val_args);
 
-           case 'p':
-             this_argclass = ptr_arg;
-             if (lcount || seen_h || seen_big_l)
-               bad = 1;
-             if (seen_prec || seen_zero || seen_space || seen_plus)
-               bad = 1;
-             break;
+  if (s == 0)
+    error_no_arg (_("format-control string and values to print"));
 
-           case 's':
-             this_argclass = lcount == 0 ? string_arg : wide_string_arg;
-             if (lcount > 1 || seen_h || seen_big_l)
-               bad = 1;
-             if (seen_zero || seen_space || seen_plus)
-               bad = 1;
-             break;
+  s = skip_spaces_const (s);
 
-           case 'e':
-           case 'f':
-           case 'g':
-           case 'E':
-           case 'G':
-             if (seen_big_h || seen_big_d || seen_double_big_d)
-               this_argclass = decfloat_arg;
-             else if (seen_big_l)
-               this_argclass = long_double_arg;
-             else
-               this_argclass = double_arg;
-
-             if (lcount || seen_h)
-               bad = 1;
-             break;
+  /* A format string should follow, enveloped in double quotes.  */
+  if (*s++ != '"')
+    error (_("Bad format string, missing '\"'."));
 
-           case '*':
-             error (_("`*' not supported for precision or width in printf"));
+  fpieces = parse_format_string (&s);
 
-           case 'n':
-             error (_("Format specifier `n' not supported in printf"));
+  make_cleanup (free_format_pieces_cleanup, &fpieces);
 
-           case '\0':
-             error (_("Incomplete format specifier at end of format string"));
+  if (*s++ != '"')
+    error (_("Bad format string, non-terminated '\"'."));
+  
+  s = skip_spaces_const (s);
 
-           default:
-             error (_("Unrecognized format specifier '%c' in printf"), *f);
-           }
+  if (*s != ',' && *s != 0)
+    error (_("Invalid argument syntax"));
 
-         if (bad)
-           error (_("Inappropriate modifiers to format specifier '%c' in printf"),
-                  *f);
+  if (*s == ',')
+    s++;
+  s = skip_spaces_const (s);
 
-         f++;
+  {
+    int nargs = 0;
+    int nargs_wanted;
+    int i, fr;
+    char *current_substring;
 
-         if (lcount > 1 && USE_PRINTF_I64)
-           {
-             /* Windows' printf does support long long, but not the usual way.
-                Convert %lld to %I64d.  */
-             int length_before_ll = f - last_arg - 1 - lcount;
-             strncpy (current_substring, last_arg, length_before_ll);
-             strcpy (current_substring + length_before_ll, "I64");
-             current_substring[length_before_ll + 3] =
-               last_arg[length_before_ll + lcount];
-             current_substring += length_before_ll + 4;
-           }
-         else if (this_argclass == wide_string_arg
-                  || this_argclass == wide_char_arg)
-           {
-             /* Convert %ls or %lc to %s.  */
-             int length_before_ls = f - last_arg - 2;
-             strncpy (current_substring, last_arg, length_before_ls);
-             strcpy (current_substring + length_before_ls, "s");
-             current_substring += length_before_ls + 2;
-           }
-         else
-           {
-             strncpy (current_substring, last_arg, f - last_arg);
-             current_substring += f - last_arg;
-           }
-         *current_substring++ = '\0';
-         last_arg = f;
-         argclass[nargs_wanted++] = this_argclass;
-       }
+    nargs_wanted = 0;
+    for (fr = 0; fpieces[fr].string != NULL; fr++)
+      if (fpieces[fr].argclass != literal_piece)
+       ++nargs_wanted;
 
     /* Now, parse all arguments and evaluate them.
        Store the VALUEs in VAL_ARGS.  */
 
     while (*s != '\0')
       {
-       char *s1;
+       const char *s1;
+
        if (nargs == allocated_args)
          val_args = (struct value **) xrealloc ((char *) val_args,
                                                 (allocated_args *= 2)
@@ -2235,81 +2306,24 @@ printf_command (char *arg, int from_tty)
       error (_("Wrong number of arguments for specified format-string"));
 
     /* Now actually print them.  */
-    current_substring = substrings;
-    for (i = 0; i < nargs; i++)
+    i = 0;
+    for (fr = 0; fpieces[fr].string != NULL; fr++)
       {
-       switch (argclass[i])
+       current_substring = fpieces[fr].string;
+       switch (fpieces[fr].argclass)
          {
          case string_arg:
-           {
-             gdb_byte *str;
-             CORE_ADDR tem;
-             int j;
-             tem = value_as_address (val_args[i]);
-
-             /* This is a %s argument.  Find the length of the string.  */
-             for (j = 0;; j++)
-               {
-                 gdb_byte c;
-                 QUIT;
-                 read_memory (tem + j, &c, 1);
-                 if (c == 0)
-                   break;
-               }
-
-             /* Copy the string contents into a string inside GDB.  */
-             str = (gdb_byte *) alloca (j + 1);
-             if (j != 0)
-               read_memory (tem, str, j);
-             str[j] = 0;
-
-             printf_filtered (current_substring, (char *) str);
-           }
+           printf_c_string (stream, current_substring, val_args[i]);
            break;
          case wide_string_arg:
-           {
-             gdb_byte *str;
-             CORE_ADDR tem;
-             int j;
-             struct type *wctype = lookup_typename ("wchar_t", NULL, 0);
-             int wcwidth = TYPE_LENGTH (wctype);
-             gdb_byte *buf = alloca (wcwidth);
-             struct obstack output;
-             struct cleanup *inner_cleanup;
-
-             tem = value_as_address (val_args[i]);
-
-             /* This is a %s argument.  Find the length of the string.  */
-             for (j = 0;; j += wcwidth)
-               {
-                 QUIT;
-                 read_memory (tem + j, buf, wcwidth);
-                 if (extract_unsigned_integer (buf, wcwidth) == 0)
-                   break;
-               }
-
-             /* Copy the string contents into a string inside GDB.  */
-             str = (gdb_byte *) alloca (j + wcwidth);
-             if (j != 0)
-               read_memory (tem, str, j);
-             memset (&str[j], 0, wcwidth);
-
-             obstack_init (&output);
-             inner_cleanup = make_cleanup_obstack_free (&output);
-
-             convert_between_encodings (target_wide_charset (),
-                                        host_charset (),
-                                        str, j, wcwidth,
-                                        &output, translit_char);
-             obstack_grow_str0 (&output, "");
-
-             printf_filtered (current_substring, obstack_base (&output));
-             do_cleanups (inner_cleanup);
-           }
+           printf_wide_c_string (stream, current_substring, val_args[i]);
            break;
          case wide_char_arg:
            {
-             struct type *wctype = lookup_typename ("wchar_t", NULL, 0);
+             struct gdbarch *gdbarch
+               = get_type_arch (value_type (val_args[i]));
+             struct type *wctype = lookup_typename (current_language, gdbarch,
+                                                    "wchar_t", NULL, 0);
              struct type *valtype;
              struct obstack output;
              struct cleanup *inner_cleanup;
@@ -2325,14 +2339,15 @@ printf_command (char *arg, int from_tty)
              obstack_init (&output);
              inner_cleanup = make_cleanup_obstack_free (&output);
 
-             convert_between_encodings (target_wide_charset (),
+             convert_between_encodings (target_wide_charset (gdbarch),
                                         host_charset (),
                                         bytes, TYPE_LENGTH (valtype),
                                         TYPE_LENGTH (valtype),
                                         &output, translit_char);
              obstack_grow_str0 (&output, "");
 
-             printf_filtered (current_substring, obstack_base (&output));
+             fprintf_filtered (stream, current_substring,
+                                obstack_base (&output));
              do_cleanups (inner_cleanup);
            }
            break;
@@ -2344,12 +2359,12 @@ printf_command (char *arg, int from_tty)
 
              /* If format string wants a float, unchecked-convert the value
                 to floating point of the same size.  */
-             type = float_type_from_length (current_gdbarch, type);
+             type = float_type_from_length (type);
              val = unpack_double (type, value_contents (val_args[i]), &inv);
              if (inv)
                error (_("Invalid floating value found in program."));
 
-             printf_filtered (current_substring, (double) val);
+              fprintf_filtered (stream, current_substring, (double) val);
              break;
            }
          case long_double_arg:
@@ -2361,22 +2376,24 @@ printf_command (char *arg, int from_tty)
 
              /* If format string wants a float, unchecked-convert the value
                 to floating point of the same size.  */
-             type = float_type_from_length (current_gdbarch, type);
+             type = float_type_from_length (type);
              val = unpack_double (type, value_contents (val_args[i]), &inv);
              if (inv)
                error (_("Invalid floating value found in program."));
 
-             printf_filtered (current_substring, (long double) val);
+             fprintf_filtered (stream, current_substring,
+                                (long double) val);
              break;
            }
 #else
            error (_("long double not supported in printf"));
 #endif
          case long_long_arg:
-#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
+#ifdef PRINTF_HAS_LONG_LONG
            {
              long long val = value_as_long (val_args[i]);
-             printf_filtered (current_substring, val);
+
+              fprintf_filtered (stream, current_substring, val);
              break;
            }
 #else
@@ -2385,187 +2402,75 @@ printf_command (char *arg, int from_tty)
          case int_arg:
            {
              int val = value_as_long (val_args[i]);
-             printf_filtered (current_substring, val);
+
+              fprintf_filtered (stream, current_substring, val);
              break;
            }
          case long_arg:
            {
              long val = value_as_long (val_args[i]);
-             printf_filtered (current_substring, val);
-             break;
-           }
-
-         /* Handles decimal floating values.  */
-       case decfloat_arg:
-           {
-             const gdb_byte *param_ptr = value_contents (val_args[i]);
-#if defined (PRINTF_HAS_DECFLOAT)
-             /* If we have native support for Decimal floating
-                printing, handle it here.  */
-             printf_filtered (current_substring, param_ptr);
-#else
-
-             /* As a workaround until vasprintf has native support for DFP
-              we convert the DFP values to string and print them using
-              the %s format specifier.  */
-
-             char *eos, *sos;
-             int nnull_chars = 0;
-
-             /* Parameter data.  */
-             struct type *param_type = value_type (val_args[i]);
-             unsigned int param_len = TYPE_LENGTH (param_type);
-
-             /* DFP output data.  */
-             struct value *dfp_value = NULL;
-             gdb_byte *dfp_ptr;
-             int dfp_len = 16;
-             gdb_byte dec[16];
-             struct type *dfp_type = NULL;
-             char decstr[MAX_DECIMAL_STRING];
-
-             /* Points to the end of the string so that we can go back
-                and check for DFP length modifiers.  */
-             eos = current_substring + strlen (current_substring);
-
-             /* Look for the float/double format specifier.  */
-             while (*eos != 'f' && *eos != 'e' && *eos != 'E'
-                    && *eos != 'g' && *eos != 'G')
-                 eos--;
-
-             sos = eos;
-
-             /* Search for the '%' char and extract the size and type of
-                the output decimal value based on its modifiers
-                (%Hf, %Df, %DDf).  */
-             while (*--sos != '%')
-               {
-                 if (*sos == 'H')
-                   {
-                     dfp_len = 4;
-                     dfp_type = builtin_type (current_gdbarch)->builtin_decfloat;
-                   }
-                 else if (*sos == 'D' && *(sos - 1) == 'D')
-                   {
-                     dfp_len = 16;
-                     dfp_type = builtin_type (current_gdbarch)->builtin_declong;
-                     sos--;
-                   }
-                 else
-                   {
-                     dfp_len = 8;
-                     dfp_type = builtin_type (current_gdbarch)->builtin_decdouble;
-                   }
-               }
-
-             /* Replace %Hf, %Df and %DDf with %s's.  */
-             *++sos = 's';
-
-             /* Go through the whole format string and pull the correct
-                number of chars back to compensate for the change in the
-                format specifier.  */
-             while (nnull_chars < nargs - i)
-               {
-                 if (*eos == '\0')
-                   nnull_chars++;
-
-                 *++sos = *++eos;
-               }
-
-             /* Conversion between different DFP types.  */
-             if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
-               decimal_convert (param_ptr, param_len, dec, dfp_len);
-             else
-               /* If this is a non-trivial conversion, just output 0.
-                  A correct converted value can be displayed by explicitly
-                  casting to a DFP type.  */
-               decimal_from_string (dec, dfp_len, "0");
-
-             dfp_value = value_from_decfloat (dfp_type, dec);
-
-             dfp_ptr = (gdb_byte *) value_contents (dfp_value);
-
-             decimal_to_string (dfp_ptr, dfp_len, decstr);
-
-             /* Print the DFP value.  */
-             printf_filtered (current_substring, decstr);
 
+              fprintf_filtered (stream, current_substring, val);
              break;
-#endif
            }
-
+         /* Handles decimal floating values.  */
+         case decfloat_arg:
+           printf_decfloat (stream, current_substring, val_args[i]);
+           break;
          case ptr_arg:
-           {
-             /* We avoid the host's %p because pointers are too
-                likely to be the wrong size.  The only interesting
-                modifier for %p is a width; extract that, and then
-                handle %p as glibc would: %#x or a literal "(nil)".  */
-
-             char *p, *fmt, *fmt_p;
-#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
-             long long val = value_as_long (val_args[i]);
-#else
-             long val = value_as_long (val_args[i]);
-#endif
-
-             fmt = alloca (strlen (current_substring) + 5);
-
-             /* Copy up to the leading %.  */
-             p = current_substring;
-             fmt_p = fmt;
-             while (*p)
-               {
-                 int is_percent = (*p == '%');
-                 *fmt_p++ = *p++;
-                 if (is_percent)
-                   {
-                     if (*p == '%')
-                       *fmt_p++ = *p++;
-                     else
-                       break;
-                   }
-               }
-
-             if (val != 0)
-               *fmt_p++ = '#';
-
-             /* Copy any width.  */
-             while (*p >= '0' && *p < '9')
-               *fmt_p++ = *p++;
-
-             gdb_assert (*p == 'p' && *(p + 1) == '\0');
-             if (val != 0)
-               {
-#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
-                 *fmt_p++ = 'l';
-#endif
-                 *fmt_p++ = 'l';
-                 *fmt_p++ = 'x';
-                 *fmt_p++ = '\0';
-                 printf_filtered (fmt, val);
-               }
-             else
-               {
-                 *fmt_p++ = 's';
-                 *fmt_p++ = '\0';
-                 printf_filtered (fmt, "(nil)");
-               }
-
-             break;
-           }
+           printf_pointer (stream, current_substring, val_args[i]);
+           break;
+         case literal_piece:
+           /* Print a portion of the format string that has no
+              directives.  Note that this will not include any
+              ordinary %-specs, but it might include "%%".  That is
+              why we use printf_filtered and not puts_filtered here.
+              Also, we pass a dummy argument because some platforms
+              have modified GCC to include -Wformat-security by
+              default, which will warn here if there is no
+              argument.  */
+           fprintf_filtered (stream, current_substring, 0);
+           break;
          default:
            internal_error (__FILE__, __LINE__,
                            _("failed internal consistency check"));
          }
-       /* Skip to the next substring.  */
-       current_substring += strlen (current_substring) + 1;
+       /* Maybe advance to the next argument.  */
+       if (fpieces[fr].argclass != literal_piece)
+         ++i;
       }
-    /* Print the portion of the format string after the last argument.  */
-    puts_filtered (last_arg);
   }
   do_cleanups (old_cleanups);
 }
 
+/* Implement the "printf" command.  */
+
+static void
+printf_command (char *arg, int from_tty)
+{
+  ui_printf (arg, gdb_stdout);
+  gdb_flush (gdb_stdout);
+}
+
+/* Implement the "eval" command.  */
+
+static void
+eval_command (char *arg, int from_tty)
+{
+  struct ui_file *ui_out = mem_fileopen ();
+  struct cleanup *cleanups = make_cleanup_ui_file_delete (ui_out);
+  char *expanded;
+
+  ui_printf (arg, ui_out);
+
+  expanded = ui_file_xstrdup (ui_out, NULL);
+  make_cleanup (xfree, expanded);
+
+  execute_command (expanded, from_tty);
+
+  do_cleanups (cleanups);
+}
+
 void
 _initialize_printcmd (void)
 {
@@ -2573,7 +2478,7 @@ _initialize_printcmd (void)
 
   current_display_number = -1;
 
-  observer_attach_solib_unloaded (clear_dangling_display_expressions);
+  observer_attach_free_objfile (clear_dangling_display_expressions);
 
   add_info ("address", address_info,
            _("Describe where symbol SYM is stored."));
@@ -2587,7 +2492,8 @@ Examine memory: x/FMT ADDRESS.\n\
 ADDRESS is an expression for the memory address to examine.\n\
 FMT is a repeat count followed by a format letter and a size letter.\n\
 Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\
-  t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n\
+  t(binary), f(float), a(address), i(instruction), c(char), s(string)\n\
+  and z(hex, zero padded on the left).\n\
 Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\
 The specified number of objects of the specified size are printed\n\
 according to the format.\n\n\
@@ -2620,7 +2526,7 @@ and examining is done as in the \"x\" command.\n\n\
 With no argument, display all currently requested auto-display expressions.\n\
 Use \"undisplay\" to cancel display requests previously made."));
 
-  add_cmd ("display", class_vars, enable_display, _("\
+  add_cmd ("display", class_vars, enable_display_command, _("\
 Enable some expressions to be displayed when program stops.\n\
 Arguments are the code numbers of the expressions to resume displaying.\n\
 No argument means enable all automatic-display expressions.\n\
@@ -2668,7 +2574,7 @@ Use \"set variable\" for variables with names identical to set subcommands.\n\
 \nWith a subcommand, this command modifies parts of the gdb environment.\n\
 You can see these environment settings with the \"show\" command."));
 
-  /* "call" is the same as "set", but handy for dbx users to call fns. */
+  /* "call" is the same as "set", but handy for dbx users to call fns.  */
   c = add_com ("call", class_vars, call_command, _("\
 Call a function in the program.\n\
 The argument is the function name and arguments, in the notation of the\n\
@@ -2709,16 +2615,17 @@ EXP may be preceded with /FMT, where FMT is a format letter\n\
 but no count or size letter (see \"x\" command)."));
   set_cmd_completer (c, expression_completer);
   add_com_alias ("p", "print", class_vars, 1);
-
-  c = add_com ("inspect", class_vars, inspect_command, _("\
-Same as \"print\" command, except that if you are running in the epoch\n\
-environment, the value is printed in its own window."));
-  set_cmd_completer (c, expression_completer);
+  add_com_alias ("inspect", "print", class_vars, 1);
 
   add_setshow_uinteger_cmd ("max-symbolic-offset", no_class,
                            &max_symbolic_offset, _("\
 Set the largest offset that will be printed in <symbol+1234> form."), _("\
-Show the largest offset that will be printed in <symbol+1234> form."), NULL,
+Show the largest offset that will be printed in <symbol+1234> form."), _("\
+Tell GDB to only display the symbolic form of an address if the\n\
+offset between the closest earlier symbol and the address is less than\n\
+the specified maximum offset.  The default is \"unlimited\", which tells GDB\n\
+to always print the symbolic form of an address if any symbol precedes\n\
+it.  Zero is equivalent to \"unlimited\"."),
                            NULL,
                            show_max_symbolic_offset,
                            &setprintlist, &showprintlist);
@@ -2730,14 +2637,7 @@ Show printing of source filename and line number with <symbol>."), NULL,
                           show_print_symbol_filename,
                           &setprintlist, &showprintlist);
 
-  /* For examine/instruction a single byte quantity is specified as
-     the data.  This avoids problems with value_at_lazy() requiring a
-     valid data type (and rejecting VOID). */
-  examine_i_type = init_type (TYPE_CODE_INT, 1, 0, "examine_i_type", NULL);
-
-  examine_b_type = init_type (TYPE_CODE_INT, 1, 0, "examine_b_type", NULL);
-  examine_h_type = init_type (TYPE_CODE_INT, 2, 0, "examine_h_type", NULL);
-  examine_w_type = init_type (TYPE_CODE_INT, 4, 0, "examine_w_type", NULL);
-  examine_g_type = init_type (TYPE_CODE_INT, 8, 0, "examine_g_type", NULL);
-
+  add_com ("eval", no_class, eval_command, _("\
+Convert \"printf format string\", arg1, arg2, arg3, ..., argn to\n\
+a command line, and call it."));
 }