2011-03-02 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 5533faafe5f1badb5a4df5c1323ea1bd75a71391..12249a004b0fe5b3c55d8ae21723e3b44b9673c9 100644 (file)
@@ -2,7 +2,7 @@
 
    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.
+   2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #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"
 
 #ifdef TUI
-#include "tui/tui.h"           /* For tui_active et.al.   */
+#include "tui/tui.h"           /* For tui_active et al.   */
 #endif
 
 #if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG)
@@ -61,7 +62,8 @@
 # define USE_PRINTF_I64 0
 #endif
 
-extern int asm_demangle;       /* Whether to demangle syms in asm printouts */
+extern int asm_demangle;       /* Whether to demangle syms in asm
+                                  printouts.  */
 
 struct format_data
   {
@@ -108,8 +110,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);
 }
 
@@ -120,8 +123,8 @@ 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);
 }
 
@@ -135,17 +138,26 @@ 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 */
+
+    /* Program space associated with `block'.  */
+    struct program_space *pspace;
+
+    /* Innermost block required by this expression when evaluated.  */
     struct block *block;
-    /* Status of this display (enabled or disabled) */
+
+    /* Status of this display (enabled or disabled).  */
     int enabled_p;
   };
 
@@ -156,13 +168,18 @@ static struct display *display_chain;
 
 static int display_number;
 
-/* Prototypes for exported functions. */
+/* Walk the following statement or block through all displays.  */
+
+#define ALL_DISPLAYS(B)                                \
+  for (B = display_chain; B; B = B->next)
+
+/* Prototypes for exported functions.  */
 
 void output_command (char *, int);
 
 void _initialize_printcmd (void);
 
-/* Prototypes for local functions. */
+/* Prototypes for local functions.  */
 
 static void do_one_display (struct display *);
 \f
@@ -250,6 +267,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;
@@ -282,10 +305,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;
 
@@ -293,7 +317,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;
        }
@@ -308,10 +333,13 @@ 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.
@@ -334,11 +362,8 @@ float_type_from_length (struct type *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,
@@ -350,18 +375,8 @@ print_scalar_formatted (const void *valaddr, struct type *type,
   unsigned int len = TYPE_LENGTH (type);
   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
@@ -448,15 +463,16 @@ 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;
 
+       opts.format = 0;
        if (TYPE_UNSIGNED (type))
          type = builtin_type (gdbarch)->builtin_true_unsigned_char;
        else
@@ -517,7 +533,7 @@ 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;
@@ -552,7 +568,8 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
    settings of the demangle and asm_demangle variables.  */
 
 void
-print_address_symbolic (CORE_ADDR addr, struct ui_file *stream,
+print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
+                       struct ui_file *stream,
                        int do_demangle, char *leadin)
 {
   char *name = NULL;
@@ -565,7 +582,7 @@ 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);
@@ -599,13 +616,14 @@ print_address_symbolic (CORE_ADDR addr, struct ui_file *stream,
 }
 
 /* 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 */
@@ -648,6 +666,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);
@@ -708,10 +733,31 @@ 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, " ");
+}
+
+/* Return a prefix for instruction address:
+   "=> " for current instruction, else "   ".  */
+
+const char *
+pc_prefix (CORE_ADDR addr)
+{
+  if (has_stack_frames ())
+    {
+      struct frame_info *frame;
+      CORE_ADDR pc;
+
+      frame = get_selected_frame (NULL);
+      pc = get_frame_pc (frame);
+
+      if (pc == addr)
+       return "=> ";
+    }
+  return "   ";
 }
 
 /* Print address ADDR symbolically on STREAM.  Parameter DEMANGLE
@@ -720,10 +766,11 @@ print_address (CORE_ADDR addr, struct ui_file *stream)
    or not.  */
 
 void
-print_address_demangle (CORE_ADDR addr, struct ui_file *stream,
-                       int do_demangle)
+print_address_demangle (struct gdbarch *gdbarch, CORE_ADDR addr,
+                       struct ui_file *stream, int do_demangle)
 {
   struct value_print_options opts;
+
   get_user_print_options (&opts);
   if (addr == 0)
     {
@@ -731,12 +778,12 @@ print_address_demangle (CORE_ADDR addr, struct ui_file *stream,
     }
   else 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, "");
+      print_address_symbolic (gdbarch, addr, stream, do_demangle, "");
     }
 }
 \f
@@ -761,9 +808,11 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
   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 (size == 'a')
@@ -790,6 +839,28 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
   else if (size == 'g')
     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')
     maxelts = 4;
@@ -806,7 +877,9 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, 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 +901,7 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, 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)
@@ -889,7 +962,6 @@ 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;
@@ -1006,6 +1078,7 @@ set_command (char *exp, int from_tty)
   struct expression *expr = parse_expression (exp);
   struct cleanup *old_chain =
     make_cleanup (free_current_contents, &expr);
+
   evaluate_expression (expr);
   do_cleanups (old_chain);
 }
@@ -1111,14 +1184,14 @@ address_info (char *exp, int from_tty)
   struct minimal_symbol *msymbol;
   long val;
   struct obj_section *section;
-  CORE_ADDR load_addr;
+  CORE_ADDR load_addr, context_pc = 0;
   int is_a_field_of_this;      /* C++: lookup_symbol sets this to nonzero
-                                  if exp is a field of `this'. */
+                                  if exp 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)
     {
@@ -1139,20 +1212,21 @@ address_info (char *exp, int from_tty)
 
       if (msymbol != NULL)
        {
+         gdbarch = get_objfile_arch (msymbol_objfile (msymbol));
          load_addr = SYMBOL_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);
          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);
            }
@@ -1180,13 +1254,13 @@ 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);
        }
@@ -1198,7 +1272,8 @@ address_info (char *exp, int from_tty)
         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);
+      SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, context_pc,
+                                                   gdb_stdout);
       break;
 
     case LOC_REGISTER:
@@ -1220,13 +1295,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 +1333,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);
        }
@@ -1285,16 +1360,17 @@ address_info (char *exp, int from_tty)
                && (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),
+                              section->objfile->name);
            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);
                  }
@@ -1347,7 +1423,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'  && */ 
@@ -1367,11 +1443,14 @@ x_command (char *exp, int from_tty)
   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
@@ -1445,6 +1524,7 @@ 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;
@@ -1481,35 +1561,26 @@ 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.
@@ -1533,25 +1604,31 @@ undisplay_command (char *args, int from_tty)
   while (*p)
     {
       p1 = p;
-      while (*p1 >= '0' && *p1 <= '9')
-       p1++;
-      if (*p1 && *p1 != ' ' && *p1 != '\t')
-       error (_("Arguments must be display numbers."));
 
-      num = atoi (p);
+      num = get_number_or_range (&p1);
+      if (num == 0)
+       warning (_("bad display number at or near '%s'"), p);
+      else
+       {
+         struct display *d;
 
-      delete_display (num);
+         ALL_DISPLAYS (d)
+           if (d->number == num)
+             break;
+         if (d == NULL)
+           printf_unfiltered (_("No display number %d.\n"), num);
+         else
+           delete_display (d);
+       }
 
       p = p1;
-      while (*p == ' ' || *p == '\t')
-       p++;
     }
   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)
@@ -1561,9 +1638,24 @@ do_one_display (struct display *d)
   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;
@@ -1581,7 +1673,12 @@ 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)
@@ -1693,8 +1790,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;
@@ -1794,50 +1892,6 @@ disable_display_command (char *args, int from_tty)
       }
 }
 
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
-   is unloaded), otherwise return 0.  */
-
-static int
-display_uses_solib_p (const struct display *d,
-                     const struct so_list *solib)
-{
-  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);
-
-         if (block != NULL
-             && solib_contains_address_p (solib, block->startaddr))
-           return 1;
-
-         if (section && section->objfile == solib->objfile)
-           return 1;
-       }
-      endpos -= oplen;
-    }
-
-  return 0;
-}
-
 /* display_chain items point to blocks and expressions.  Some expressions in
    turn may point to symbols.
    Both symbols and blocks are obstack_alloc'd on objfile_stack, and are
@@ -1849,17 +1903,28 @@ display_uses_solib_p (const struct display *d,
 static void
 clear_dangling_display_expressions (struct so_list *solib)
 {
+  struct objfile *objfile = solib->objfile;
   struct display *d;
-  struct objfile *objfile = NULL;
 
-  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;
+  if (objfile->separate_debug_objfile_backlink)
+    objfile = objfile->separate_debug_objfile_backlink;
+  gdb_assert (objfile->pspace == solib->pspace);
+
+  for (d = display_chain; d != NULL; d = d->next)
     {
-      if (d->exp && display_uses_solib_p (d, solib))
-       {
-         xfree (d->exp);
-         d->exp = NULL;
-         d->block = NULL;
-       }
+      if (d->pspace != solib->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
@@ -1875,22 +1940,31 @@ 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);
-  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);
+    }
+  if (except.reason < 0)
+    fprintf_filtered(stream, "<error reading variable %s (%s)>", name,
+                    except.message);
   fprintf_filtered (stream, "\n");
 }
 
+/* printf "printf format string" ARG to STREAM.  */
+
 static void
-printf_command (char *arg, int from_tty)
+ui_printf (char *arg, struct ui_file *stream)
 {
   char *f = NULL;
   char *s = arg;
@@ -1908,9 +1982,7 @@ printf_command (char *arg, int from_tty)
   if (s == 0)
     error_no_arg (_("format-control string and values to print"));
 
-  /* Skip white space before format string */
-  while (*s == ' ' || *s == '\t')
-    s++;
+  s = skip_spaces (s);
 
   /* A format string should follow, enveloped in double quotes.  */
   if (*s++ != '"')
@@ -1960,7 +2032,7 @@ printf_command (char *arg, int from_tty)
              *f++ = '"';
              break;
            default:
-             /* ??? TODO: handle other escape sequences */
+             /* ??? TODO: handle other escape sequences */
              error (_("Unrecognized escape character \\%c in format string."),
                     c);
            }
@@ -1974,16 +2046,14 @@ printf_command (char *arg, int from_tty)
   /* Skip over " and following space and comma.  */
   s++;
   *f++ = '\0';
-  while (*s == ' ' || *s == '\t')
-    s++;
+  s = skip_spaces (s);
 
   if (*s != ',' && *s != 0)
     error (_("Invalid argument syntax"));
 
   if (*s == ',')
     s++;
-  while (*s == ' ' || *s == '\t')
-    s++;
+  s = skip_spaces (s);
 
   /* Need extra space for the '\0's.  Doubling the size is sufficient.  */
   substrings = alloca (strlen (string) * 2);
@@ -2182,7 +2252,8 @@ printf_command (char *arg, int from_tty)
            }
 
          if (bad)
-           error (_("Inappropriate modifiers to format specifier '%c' in printf"),
+           error (_("Inappropriate modifiers to "
+                    "format specifier '%c' in printf"),
                   *f);
 
          f++;
@@ -2192,6 +2263,7 @@ printf_command (char *arg, int from_tty)
              /* 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] =
@@ -2203,6 +2275,7 @@ printf_command (char *arg, int from_tty)
            {
              /* 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;
@@ -2223,6 +2296,7 @@ printf_command (char *arg, int from_tty)
     while (*s != '\0')
       {
        char *s1;
+
        if (nargs == allocated_args)
          val_args = (struct value **) xrealloc ((char *) val_args,
                                                 (allocated_args *= 2)
@@ -2250,12 +2324,14 @@ printf_command (char *arg, int from_tty)
              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)
@@ -2268,7 +2344,7 @@ printf_command (char *arg, int from_tty)
                read_memory (tem, str, j);
              str[j] = 0;
 
-             printf_filtered (current_substring, (char *) str);
+              fprintf_filtered (stream, current_substring, (char *) str);
            }
            break;
          case wide_string_arg:
@@ -2278,6 +2354,7 @@ printf_command (char *arg, int from_tty)
              int j;
              struct gdbarch *gdbarch
                = get_type_arch (value_type (val_args[i]));
+             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);
@@ -2292,7 +2369,7 @@ printf_command (char *arg, int from_tty)
                {
                  QUIT;
                  read_memory (tem + j, buf, wcwidth);
-                 if (extract_unsigned_integer (buf, wcwidth) == 0)
+                 if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0)
                    break;
                }
 
@@ -2305,13 +2382,14 @@ 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 (),
                                         str, j, wcwidth,
                                         &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;
@@ -2336,14 +2414,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;
@@ -2360,7 +2439,7 @@ printf_command (char *arg, int from_tty)
              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:
@@ -2377,7 +2456,8 @@ printf_command (char *arg, int from_tty)
              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
@@ -2387,7 +2467,8 @@ printf_command (char *arg, int from_tty)
 #if defined (CC_HAS_LONG_LONG) && defined (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
@@ -2396,13 +2477,15 @@ 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);
+
+              fprintf_filtered (stream, current_substring, val);
              break;
            }
 
@@ -2410,10 +2493,11 @@ printf_command (char *arg, int from_tty)
        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);
+              fprintf_filtered (stream, current_substring, param_ptr);
 #else
 
              /* As a workaround until vasprintf has native support for DFP
@@ -2427,6 +2511,7 @@ printf_command (char *arg, int from_tty)
              struct type *param_type = value_type (val_args[i]);
              unsigned int param_len = TYPE_LENGTH (param_type);
              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;
@@ -2486,21 +2571,22 @@ printf_command (char *arg, int from_tty)
 
              /* Conversion between different DFP types.  */
              if (TYPE_CODE (param_type) == TYPE_CODE_DECFLOAT)
-               decimal_convert (param_ptr, param_len, dec, dfp_len);
+               decimal_convert (param_ptr, param_len, 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, "0");
+               decimal_from_string (dec, dfp_len, byte_order, "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);
+             decimal_to_string (dfp_ptr, dfp_len, byte_order, decstr);
 
              /* Print the DFP value.  */
-             printf_filtered (current_substring, decstr);
+              fprintf_filtered (stream, current_substring, decstr);
 
              break;
 #endif
@@ -2528,6 +2614,7 @@ printf_command (char *arg, int from_tty)
              while (*p)
                {
                  int is_percent = (*p == '%');
+
                  *fmt_p++ = *p++;
                  if (is_percent)
                    {
@@ -2554,13 +2641,13 @@ printf_command (char *arg, int from_tty)
                  *fmt_p++ = 'l';
                  *fmt_p++ = 'x';
                  *fmt_p++ = '\0';
-                 printf_filtered (fmt, val);
+                  fprintf_filtered (stream, fmt, val);
                }
              else
                {
                  *fmt_p++ = 's';
                  *fmt_p++ = '\0';
-                 printf_filtered (fmt, "(nil)");
+                  fprintf_filtered (stream, fmt, "(nil)");
                }
 
              break;
@@ -2572,12 +2659,44 @@ printf_command (char *arg, int from_tty)
        /* Skip to the next substring.  */
        current_substring += strlen (current_substring) + 1;
       }
-    /* Print the portion of the format string after the last argument.  */
-    puts_filtered (last_arg);
+    /* Print the portion of the format string after the last argument.
+       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, last_arg, 0);
   }
   do_cleanups (old_cleanups);
 }
 
+/* Implement the "printf" command.  */
+
+static void
+printf_command (char *arg, int from_tty)
+{
+  ui_printf (arg, 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)
 {
@@ -2680,7 +2799,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\
@@ -2741,4 +2860,8 @@ Show printing of source filename and line number with <symbol>."), NULL,
                           NULL,
                           show_print_symbol_filename,
                           &setprintlist, &showprintlist);
+
+  add_com ("eval", no_class, eval_command, _("\
+Convert \"printf format string\", arg1, arg2, arg3, ..., argn to\n\
+a command line, and call it."));
 }
This page took 0.074399 seconds and 4 git commands to generate.