2010-02-10 Sterling Augustine <sterling@tensilica.com>
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 59bb656898c179e461a3a4892ac3b02bda413a0b..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.
 
@@ -49,6 +49,7 @@
 #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.   */
@@ -135,16 +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;
   };
@@ -293,7 +303,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;
        }
@@ -317,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);
 
@@ -344,7 +356,7 @@ print_scalar_formatted (const void *valaddr, struct type *type,
                        const struct value_print_options *options,
                        int size, struct ui_file *stream)
 {
-  struct gdbarch *gdbarch = current_gdbarch;
+  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 (gdbarch);
@@ -447,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;
 
@@ -466,7 +478,7 @@ print_scalar_formatted (const void *valaddr, struct type *type,
       break;
 
     case 'f':
-      type = float_type_from_length (current_gdbarch, type);
+      type = float_type_from_length (type);
       print_floating (valaddr, type, stream);
       break;
 
@@ -551,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;
@@ -564,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);
@@ -604,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 */
@@ -647,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);
@@ -707,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
@@ -719,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);
@@ -730,12 +772,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
@@ -781,13 +823,13 @@ do_examine (struct format_data fmt, struct gdbarch *gdbarch, CORE_ADDR addr)
     }
 
   if (size == 'b')
-    val_type = builtin_type_int8;
+    val_type = builtin_type (next_gdbarch)->builtin_int8;
   else if (size == 'h')
-    val_type = builtin_type_int16;
+    val_type = builtin_type (next_gdbarch)->builtin_int16;
   else if (size == 'w')
-    val_type = builtin_type_int32;
+    val_type = builtin_type (next_gdbarch)->builtin_int32;
   else if (size == 'g')
-    val_type = builtin_type_int64;
+    val_type = builtin_type (next_gdbarch)->builtin_int64;
 
   maxelts = 8;
   if (size == 'w')
@@ -805,7 +847,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;
@@ -1138,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);
            }
@@ -1179,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);
        }
@@ -1219,13 +1264,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);
        }
@@ -1257,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);
        }
@@ -1284,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);
                  }
@@ -1444,6 +1490,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;
@@ -1560,6 +1607,20 @@ 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;
@@ -1580,7 +1641,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)
@@ -1805,6 +1871,7 @@ display_uses_solib_p (const struct display *d,
   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;
 
@@ -1821,14 +1888,14 @@ display_uses_solib_p (const struct display *d,
        {
          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))
+             && solib_contains_address_p (solib,
+                                          block->startaddr))
            return 1;
 
-         if (section && section->objfile == solib->objfile)
+         /* SYMBOL_OBJ_SECTION (symbol) may be NULL.  */
+         if (SYMBOL_SYMTAB (symbol)->objfile == solib->objfile)
            return 1;
        }
       endpos -= oplen;
@@ -2275,8 +2342,10 @@ printf_command (char *arg, int from_tty)
              gdb_byte *str;
              CORE_ADDR tem;
              int j;
-             struct type *wctype = lookup_typename (current_language,
-                                                    current_gdbarch,
+             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);
@@ -2290,7 +2359,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;
                }
 
@@ -2303,7 +2372,7 @@ 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 (byte_order),
                                         host_charset (),
                                         str, j, wcwidth,
                                         &output, translit_char);
@@ -2315,8 +2384,10 @@ printf_command (char *arg, int from_tty)
            break;
          case wide_char_arg:
            {
-             struct type *wctype = lookup_typename (current_language,
-                                                    current_gdbarch,
+             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;
@@ -2333,7 +2404,7 @@ 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 (byte_order),
                                         host_charset (),
                                         bytes, TYPE_LENGTH (valtype),
                                         TYPE_LENGTH (valtype),
@@ -2352,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."));
@@ -2369,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."));
@@ -2423,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;
@@ -2451,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;
                    }
                }
 
@@ -2482,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);
This page took 0.04928 seconds and 4 git commands to generate.