2010-02-10 Sterling Augustine <sterling@tensilica.com>
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 0dfe80be0f3386fa58f028bba1a2fc52543c6a66..c8cb35c3c1864e7f02241dbb32dcafa01c3a7863 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 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #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"
 
 #ifdef TUI
 #include "tui/tui.h"           /* For tui_active et.al.   */
@@ -62,18 +69,23 @@ struct format_data
     int count;
     char format;
     char size;
+
+    /* True if the value should be printed raw -- that is, bypassing
+       python-based formatters.  */
+    unsigned char raw;
   };
 
 /* Last specified output format.  */
 
-static char last_format = 'x';
+static char last_format = 0;
 
 /* Last specified examination size.  'b', 'h', 'w' or `q'.  */
 
 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.  */
@@ -124,14 +136,25 @@ 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;
+
+    /* 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) */
     int enabled_p;
   };
@@ -173,6 +196,7 @@ decode_format (char **string_ptr, int oformat, int osize)
   val.format = '?';
   val.size = '?';
   val.count = 1;
+  val.raw = 0;
 
   if (*p >= '0' && *p <= '9')
     val.count = atoi (p);
@@ -185,6 +209,11 @@ decode_format (char **string_ptr, int oformat, int osize)
     {
       if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g')
        val.size = *p++;
+      else if (*p == 'r')
+       {
+         val.raw = 1;
+         p++;
+       }
       else if (*p >= 'a' && *p <= 'z')
        val.format = *p++;
       else
@@ -213,18 +242,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.  */
@@ -262,24 +283,28 @@ print_formatted (struct value *val, int size,
   int len = TYPE_LENGTH (type);
 
   if (VALUE_LVAL (val) == lval_memory)
-    next_address = VALUE_ADDRESS (val) + len;
+    next_address = value_address (val) + len;
 
   if (size)
     {
       switch (options->format)
        {
        case 's':
-         /* FIXME: Need to handle wchar_t's here... */
-         next_address = VALUE_ADDRESS (val)
-           + val_print_string (VALUE_ADDRESS (val), -1, 1, stream,
-                               options);
+         {
+           struct type *elttype = value_type (val);
+           next_address = (value_address (val)
+                           + val_print_string (elttype,
+                                               value_address (val), -1,
+                                               stream, options));
+         }
          return;
 
        case 'i':
          /* We often wrap here if there are long symbolic names.  */
          wrap_here ("    ");
-         next_address = (VALUE_ADDRESS (val)
-                         + gdb_print_insn (VALUE_ADDRESS (val), stream,
+         next_address = (value_address (val)
+                         + gdb_print_insn (get_type_arch (type),
+                                           value_address (val), stream,
                                            &branch_delay_insns));
          return;
        }
@@ -303,8 +328,9 @@ print_formatted (struct value *val, int size,
 /* 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);
 
@@ -330,9 +356,10 @@ 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
@@ -367,7 +394,7 @@ print_scalar_formatted (const void *valaddr, struct type *type,
          print_hex_chars (stream, valaddr, len, byte_order);
          return;
        case 'c':
-         print_char_chars (stream, valaddr, len, byte_order);
+         print_char_chars (stream, type, valaddr, len, byte_order);
          return;
        default:
          break;
@@ -381,12 +408,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;
@@ -432,7 +459,7 @@ 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;
 
@@ -440,18 +467,18 @@ print_scalar_formatted (const void *valaddr, struct type *type,
       {
        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;
 
@@ -519,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 $_.  */
@@ -535,7 +563,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;
@@ -548,7 +577,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);
@@ -588,7 +617,8 @@ print_address_symbolic (CORE_ADDR addr, struct ui_file *stream,
    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 */
@@ -602,7 +632,7 @@ build_address_symbolic (CORE_ADDR addr,  /* IN */
   struct obj_section *section = NULL;
   char *name_temp = "";
   
-  /* Let's say it is unmapped.  */
+  /* Let's say it is mapped (not unmapped).  */
   *unmapped = 0;
 
   /* Determine if the address is in an overlay, and whether it is
@@ -631,6 +661,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);
@@ -691,10 +728,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 (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)
 {
-  fputs_filtered (paddress (addr), stream);
-  print_address_symbolic (addr, stream, asm_demangle, " ");
+  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
@@ -703,8 +761,8 @@ 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);
@@ -714,31 +772,21 @@ 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
 
-/* 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;
@@ -751,6 +799,7 @@ 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
@@ -758,16 +807,29 @@ do_examine (struct format_data fmt, CORE_ADDR addr)
   if (format == 's' || 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;
 
   maxelts = 8;
   if (size == 'w')
@@ -785,7 +847,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;
@@ -863,6 +927,7 @@ print_command_1 (char *exp, int inspect, int voidprint)
       fmt.count = 1;
       fmt.format = 0;
       fmt.size = 0;
+      fmt.raw = 0;
     }
 
   if (exp && *exp)
@@ -898,6 +963,7 @@ print_command_1 (char *exp, int inspect, int voidprint)
 
       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");
@@ -948,6 +1014,7 @@ output_command (char *exp, int from_tty)
   struct value_print_options opts;
 
   fmt.size = 0;
+  fmt.raw = 0;
 
   if (exp && *exp == '/')
     {
@@ -965,6 +1032,7 @@ output_command (char *exp, int from_tty)
   annotate_value_begin (value_type (val));
 
   get_formatted_print_options (&opts, format);
+  opts.raw = fmt.raw;
   print_formatted (val, fmt.size, &opts, gdb_stdout);
 
   annotate_value_end ();
@@ -1025,9 +1093,9 @@ sym_info (char *arg, int from_tty)
        /* Don't print the offset if it is zero.
           We assume there's no need to handle i18n of "sym + offset".  */
        if (offset)
-         xasprintf (&loc_string, "%s + %u", msym_name, offset);
+         loc_string = xstrprintf ("%s + %u", msym_name, offset);
        else
-         xasprintf (&loc_string, "%s", msym_name);
+         loc_string = xstrprintf ("%s", msym_name);
 
        /* Use a cleanup to free loc_string in case the user quits
           a pagination request inside printf_filtered.  */
@@ -1080,6 +1148,8 @@ sym_info (char *arg, int from_tty)
 static void
 address_info (char *exp, int from_tty)
 {
+  struct gdbarch *gdbarch;
+  int regno;
   struct symbol *sym;
   struct minimal_symbol *msymbol;
   long val;
@@ -1112,20 +1182,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);
            }
@@ -1142,6 +1213,7 @@ address_info (char *exp, int from_tty)
   printf_filtered ("\" is ");
   val = SYMBOL_VALUE (sym);
   section = SYMBOL_OBJ_SECTION (sym);
+  gdbarch = get_objfile_arch (SYMBOL_SYMTAB (sym)->objfile);
 
   switch (SYMBOL_CLASS (sym))
     {
@@ -1152,13 +1224,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);
        }
@@ -1166,39 +1238,49 @@ address_info (char *exp, int from_tty)
 
     case LOC_COMPUTED:
       /* FIXME: cagney/2004-01-26: It should be possible to
-        unconditionally call the SYMBOL_OPS method when available.
+        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_OPS (sym)->describe_location (sym, gdb_stdout);
+      SYMBOL_COMPUTED_OPS (sym)->describe_location (sym, gdb_stdout);
       break;
 
     case LOC_REGISTER:
+      /* GDBARCH is the architecture associated with the objfile the symbol
+        is defined in; the target architecture may be different, and may
+        provide additional registers.  However, we do not know the target
+        architecture at this point.  We assume the objfile architecture
+        will contain all the standard registers that occur in debug info
+        in that objfile.  */
+      regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
+
       if (SYMBOL_IS_ARGUMENT (sym))
        printf_filtered (_("an argument in register %s"),
-                        gdbarch_register_name (current_gdbarch, val));
+                        gdbarch_register_name (gdbarch, regno));
       else
        printf_filtered (_("a variable in register %s"),
-                        gdbarch_register_name (current_gdbarch, val));
+                        gdbarch_register_name (gdbarch, regno));
       break;
 
     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);
        }
       break;
 
     case LOC_REGPARM_ADDR:
+      /* Note comment at LOC_REGISTER.  */
+      regno = SYMBOL_REGISTER_OPS (sym)->register_number (sym, gdbarch);
       printf_filtered (_("address of an argument in register %s"),
-                      gdbarch_register_name (current_gdbarch, val));
+                      gdbarch_register_name (gdbarch, regno));
       break;
 
     case LOC_ARG:
@@ -1220,12 +1302,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);
        }
@@ -1247,16 +1329,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);
                  }
@@ -1285,9 +1368,10 @@ x_command (char *exp, int from_tty)
   struct cleanup *old_chain;
   struct value *val;
 
-  fmt.format = last_format;
+  fmt.format = last_format ? last_format : 'x';
   fmt.size = last_size;
   fmt.count = 1;
+  fmt.raw = 0;
 
   if (exp && *exp == '/')
     {
@@ -1314,13 +1398,18 @@ x_command (char *exp, int from_tty)
       if (/* last_format == 'i'  && */ 
          TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
           && VALUE_LVAL (val) == lval_memory)
-       next_address = VALUE_ADDRESS (val);
+       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.  */
@@ -1343,8 +1432,7 @@ x_command (char *exp, int from_tty)
         then don't fetch it now; instead mark it by voiding the $__
         variable.  */
       if (value_lazy (last_examine_value))
-       set_internalvar (lookup_internalvar ("__"),
-                        allocate_value (builtin_type_void));
+       clear_internalvar (lookup_internalvar ("__"));
       else
        set_internalvar (lookup_internalvar ("__"), last_examine_value);
     }
@@ -1391,15 +1479,18 @@ display_command (char *exp, int from_tty)
          fmt.format = 0;
          fmt.size = 0;
          fmt.count = 0;
+         fmt.raw = 0;
        }
 
-      innermost_block = 0;
+      innermost_block = NULL;
       expr = parse_expression (exp);
 
       new = (struct display *) xmalloc (sizeof (struct display));
 
+      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;
@@ -1416,6 +1507,7 @@ display_command (char *exp, int from_tty)
 static void
 free_display (struct display *d)
 {
+  xfree (d->exp_string);
   xfree (d->exp);
   xfree (d);
 }
@@ -1430,9 +1522,8 @@ clear_displays (void)
 
   while ((d = display_chain) != NULL)
     {
-      xfree (d->exp);
       display_chain = d->next;
-      xfree (d);
+      free_display (d);
     }
 }
 
@@ -1479,7 +1570,7 @@ undisplay_command (char *args, int from_tty)
 
   if (args == 0)
     {
-      if (query ("Delete all auto-display expressions? "))
+      if (query (_("Delete all auto-display expressions? ")))
        clear_displays ();
       dont_repeat ();
       return;
@@ -1516,8 +1607,46 @@ 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;
+         d->exp = parse_expression (d->exp_string);
+         d->block = innermost_block;
+       }
+      if (ex.reason < 0)
+       {
+         /* Can't re-parse the expression.  Disable this display item.  */
+         d->enabled_p = 0;
+         warning (_("Unable to display \"%s\": %s"),
+                  d->exp_string, ex.message);
+         return;
+       }
+    }
+
   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)
@@ -1546,7 +1675,7 @@ do_one_display (struct display *d)
 
       annotate_display_expression ();
 
-      print_expression (d->exp, gdb_stdout);
+      puts_filtered (d->exp_string);
       annotate_display_expression_end ();
 
       if (d->format.count != 1 || d->format.format == 'i')
@@ -1557,11 +1686,11 @@ do_one_display (struct display *d)
       val = evaluate_expression (d->exp);
       addr = value_as_address (val);
       if (d->format.format == 'i')
-       addr = gdbarch_addr_bits_remove (current_gdbarch, addr);
+       addr = gdbarch_addr_bits_remove (d->exp->gdbarch, addr);
 
       annotate_display_value ();
 
-      do_examine (d->format, addr);
+      do_examine (d->format, d->exp->gdbarch, addr);
     }
   else
     {
@@ -1574,7 +1703,7 @@ do_one_display (struct display *d)
 
       annotate_display_expression ();
 
-      print_expression (d->exp, gdb_stdout);
+      puts_filtered (d->exp_string);
       annotate_display_expression_end ();
 
       printf_filtered (" = ");
@@ -1582,6 +1711,7 @@ do_one_display (struct display *d)
       annotate_display_expression ();
 
       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);
       printf_filtered ("\n");
@@ -1654,7 +1784,7 @@ Num Enb Expression\n"));
                         d->format.format);
       else if (d->format.format)
        printf_filtered ("/%c ", d->format.format);
-      print_expression (d->exp, gdb_stdout);
+      puts_filtered (d->exp_string);
       if (d->block && !contained_in (get_selected_block (0), d->block))
        printf_filtered (_(" (cannot be evaluated in the current context)"));
       printf_filtered ("\n");
@@ -1728,6 +1858,76 @@ disable_display_command (char *args, int from_tty)
          p++;
       }
 }
+
+/* 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
+      && d->pspace == solib->pspace
+      && 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;
+
+         if (block != NULL
+             && solib_contains_address_p (solib,
+                                          block->startaddr))
+           return 1;
+
+         /* SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
+         if (SYMBOL_SYMTAB (symbol)->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
+   obstack_free'd when a shared library is unloaded.
+   Clear pointers that are about to become dangling.
+   Both .exp and .block fields will be restored next time we need to display
+   an item by re-parsing .exp_string field in the new execution context.  */
+
+static void
+clear_dangling_display_expressions (struct so_list *solib)
+{
+  struct display *d;
+  struct objfile *objfile = NULL;
+
+  for (d = display_chain; d; d = d->next)
+    {
+      if (d->exp && display_uses_solib_p (d, solib))
+       {
+         xfree (d->exp);
+         d->exp = NULL;
+         d->block = NULL;
+       }
+    }
+}
 \f
 
 /* Print the value in stack frame FRAME of a variable specified by a
@@ -1862,7 +2062,8 @@ printf_command (char *arg, int from_tty)
 
     enum argclass
       {
-       int_arg, long_arg, long_long_arg, ptr_arg, string_arg,
+       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;
@@ -1994,8 +2195,8 @@ printf_command (char *arg, int from_tty)
              break;
 
            case 'c':
-             this_argclass = int_arg;
-             if (lcount || seen_h || seen_big_l)
+             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;
@@ -2010,8 +2211,8 @@ printf_command (char *arg, int from_tty)
              break;
 
            case 's':
-             this_argclass = string_arg;
-             if (lcount || seen_h || seen_big_l)
+             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;
@@ -2063,6 +2264,15 @@ printf_command (char *arg, int from_tty)
                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);
@@ -2127,6 +2337,84 @@ printf_command (char *arg, int from_tty)
              printf_filtered (current_substring, (char *) str);
            }
            break;
+         case wide_string_arg:
+           {
+             gdb_byte *str;
+             CORE_ADDR tem;
+             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);
+             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, byte_order) == 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 (byte_order),
+                                        host_charset (),
+                                        str, j, wcwidth,
+                                        &output, translit_char);
+             obstack_grow_str0 (&output, "");
+
+             printf_filtered (current_substring, obstack_base (&output));
+             do_cleanups (inner_cleanup);
+           }
+           break;
+         case wide_char_arg:
+           {
+             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);
+             struct type *valtype;
+             struct obstack output;
+             struct cleanup *inner_cleanup;
+             const gdb_byte *bytes;
+
+             valtype = value_type (val_args[i]);
+             if (TYPE_LENGTH (valtype) != TYPE_LENGTH (wctype)
+                 || TYPE_CODE (valtype) != TYPE_CODE_INT)
+               error (_("expected wchar_t argument for %%lc"));
+
+             bytes = value_contents (val_args[i]);
+
+             obstack_init (&output);
+             inner_cleanup = make_cleanup_obstack_free (&output);
+
+             convert_between_encodings (target_wide_charset (byte_order),
+                                        host_charset (),
+                                        bytes, TYPE_LENGTH (valtype),
+                                        TYPE_LENGTH (valtype),
+                                        &output, translit_char);
+             obstack_grow_str0 (&output, "");
+
+             printf_filtered (current_substring, obstack_base (&output));
+             do_cleanups (inner_cleanup);
+           }
+           break;
          case double_arg:
            {
              struct type *type = value_type (val_args[i]);
@@ -2135,7 +2423,7 @@ 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."));
@@ -2152,7 +2440,7 @@ 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."));
@@ -2206,6 +2494,8 @@ printf_command (char *arg, int from_tty)
              /* Parameter data.  */
              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;
@@ -2234,18 +2524,18 @@ printf_command (char *arg, int from_tty)
                  if (*sos == 'H')
                    {
                      dfp_len = 4;
-                     dfp_type = builtin_type (current_gdbarch)->builtin_decfloat;
+                     dfp_type = builtin_type (gdbarch)->builtin_decfloat;
                    }
                  else if (*sos == 'D' && *(sos - 1) == 'D')
                    {
                      dfp_len = 16;
-                     dfp_type = builtin_type (current_gdbarch)->builtin_declong;
+                     dfp_type = builtin_type (gdbarch)->builtin_declong;
                      sos--;
                    }
                  else
                    {
                      dfp_len = 8;
-                     dfp_type = builtin_type (current_gdbarch)->builtin_decdouble;
+                     dfp_type = builtin_type (gdbarch)->builtin_decdouble;
                    }
                }
 
@@ -2265,18 +2555,19 @@ 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);
@@ -2364,6 +2655,8 @@ _initialize_printcmd (void)
 
   current_display_number = -1;
 
+  observer_attach_solib_unloaded (clear_dangling_display_expressions);
+
   add_info ("address", address_info,
            _("Describe where symbol SYM is stored."));
 
@@ -2518,15 +2811,4 @@ Show printing of source filename and line number with <symbol>."), NULL,
                           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);
-
 }
This page took 0.047098 seconds and 4 git commands to generate.