* elf-m10300.c (mn10300_elf_relax_section): Allow for the
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 8a746e49c4afbb7717178a5cc3517a808b592a58..eeffa6ea7d509aa7dd985bd7f99e2e01c5987be9 100644 (file)
@@ -48,6 +48,7 @@
 #include "solist.h"
 #include "solib.h"
 #include "parser-defs.h"
+#include "charset.h"
 
 #ifdef TUI
 #include "tui/tui.h"           /* For tui_active et.al.   */
@@ -67,11 +68,15 @@ 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'.  */
 
@@ -180,6 +185,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);
@@ -192,6 +198,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
@@ -269,24 +280,27 @@ 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 (value_address (val), stream,
                                            &branch_delay_insns));
          return;
        }
@@ -374,7 +388,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;
@@ -393,7 +407,7 @@ print_scalar_formatted (const void *valaddr, struct type *type,
   /* 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;
@@ -870,6 +884,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)
@@ -905,6 +920,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");
@@ -955,6 +971,7 @@ output_command (char *exp, int from_tty)
   struct value_print_options opts;
 
   fmt.size = 0;
+  fmt.raw = 0;
 
   if (exp && *exp == '/')
     {
@@ -972,6 +989,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 ();
@@ -1032,9 +1050,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.  */
@@ -1087,6 +1105,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;
@@ -1149,6 +1169,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))
     {
@@ -1173,20 +1194,28 @@ 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:
@@ -1204,8 +1233,10 @@ address_info (char *exp, int from_tty)
       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:
@@ -1292,9 +1323,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 == '/')
     {
@@ -1321,7 +1353,7 @@ 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);
       do_cleanups (old_chain);
@@ -1350,8 +1382,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);
     }
@@ -1398,6 +1429,7 @@ display_command (char *exp, int from_tty)
          fmt.format = 0;
          fmt.size = 0;
          fmt.count = 0;
+         fmt.raw = 0;
        }
 
       innermost_block = NULL;
@@ -1584,7 +1616,7 @@ 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 ();
 
@@ -1609,6 +1641,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");
@@ -1763,18 +1796,23 @@ static int
 display_uses_solib_p (const struct display *d,
                      const struct so_list *solib)
 {
-  int i;
+  int endpos;
   struct expression *const exp = d->exp;
+  const union exp_element *const elts = exp->elts;
 
   if (d->block != NULL
-      && solib_name_from_address (d->block->startaddr) == solib->so_name)
+      && solib_contains_address_p (solib, d->block->startaddr))
     return 1;
 
-  for (i = 0; i < exp->nelts; )
+  for (endpos = exp->nelts; endpos > 0; )
     {
-      int args, oplen = 0;
-      const union exp_element *const elts = exp->elts;
+      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;
@@ -1783,17 +1821,15 @@ display_uses_solib_p (const struct display *d,
            SYMBOL_OBJ_SECTION (symbol);
 
          if (block != NULL
-             && solib_name_from_address (block->startaddr) == solib->so_name)
+             && solib_contains_address_p (solib, block->startaddr))
            return 1;
 
          if (section && section->objfile == solib->objfile)
            return 1;
        }
-      exp->language_defn->la_exp_desc->operator_length (exp, i + 1,
-                                                       &oplen, &args);
-      gdb_assert (oplen > 0);
-      i += oplen;
+      endpos -= oplen;
     }
+
   return 0;
 }
 
@@ -1955,7 +1991,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;
@@ -2087,8 +2124,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;
@@ -2103,8 +2140,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;
@@ -2156,6 +2193,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);
@@ -2220,6 +2266,80 @@ 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 type *wctype = lookup_typename (current_language,
+                                                    current_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) == 0)
+                   break;
+               }
+
+             /* Copy the string contents into a string inside GDB.  */
+             str = (gdb_byte *) alloca (j + wcwidth);
+             if (j != 0)
+               read_memory (tem, str, j);
+             memset (&str[j], 0, wcwidth);
+
+             obstack_init (&output);
+             inner_cleanup = make_cleanup_obstack_free (&output);
+
+             convert_between_encodings (target_wide_charset (),
+                                        host_charset (),
+                                        str, j, wcwidth,
+                                        &output, translit_char);
+             obstack_grow_str0 (&output, "");
+
+             printf_filtered (current_substring, obstack_base (&output));
+             do_cleanups (inner_cleanup);
+           }
+           break;
+         case wide_char_arg:
+           {
+             struct type *wctype = lookup_typename (current_language,
+                                                    current_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 (),
+                                        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]);
This page took 0.034389 seconds and 4 git commands to generate.