Remove MULTI_OBJFILE_P
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 0509360581eaf54418e3fbd82015eb1f2421ee97..77cdd77a16115e7bce27deec51ffab0d9ea10759 100644 (file)
@@ -23,6 +23,7 @@
 #include "gdbtypes.h"
 #include "value.h"
 #include "language.h"
+#include "c-lang.h"
 #include "expression.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "cli/cli-option.h"
 #include "cli/cli-script.h"
 #include "cli/cli-style.h"
-#include "common/format.h"
+#include "gdbsupport/format.h"
 #include "source.h"
-#include "common/byte-vector.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/byte-vector.h"
+#include "gdbsupport/gdb_optional.h"
 
 /* Last specified output format.  */
 
@@ -99,7 +100,7 @@ show_max_symbolic_offset (struct ui_file *file, int from_tty,
 
 /* Append the source filename and linenumber of the symbol when
    printing a symbolic value as `<symbol at filename:linenum>' if set.  */
-static int print_symbol_filename = 0;
+static bool print_symbol_filename = false;
 static void
 show_print_symbol_filename (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
@@ -355,7 +356,7 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
 {
   struct gdbarch *gdbarch = get_type_arch (type);
   unsigned int len = TYPE_LENGTH (type);
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  enum bfd_endian byte_order = type_byte_order (type);
 
   /* String printing should go through val_print_scalar_formatted.  */
   gdb_assert (options->format != 's');
@@ -404,21 +405,30 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
 
   /* Historically gdb has printed floats by first casting them to a
      long, and then printing the long.  PR cli/16242 suggests changing
-     this to using C-style hex float format.  */
-  gdb::byte_vector converted_float_bytes;
-  if (TYPE_CODE (type) == TYPE_CODE_FLT
-      && (options->format == 'o'
-         || options->format == 'x'
-         || options->format == 't'
-         || options->format == 'z'
-         || options->format == 'd'
-         || options->format == 'u'))
-    {
-      LONGEST val_long = unpack_long (type, valaddr);
-      converted_float_bytes.resize (TYPE_LENGTH (type));
-      store_signed_integer (converted_float_bytes.data (), TYPE_LENGTH (type),
-                           byte_order, val_long);
-      valaddr = converted_float_bytes.data ();
+     this to using C-style hex float format.
+
+     Biased range types must also be unbiased here; the unbiasing is
+     done by unpack_long.  */
+  gdb::byte_vector converted_bytes;
+  /* Some cases below will unpack the value again.  In the biased
+     range case, we want to avoid this, so we store the unpacked value
+     here for possible use later.  */
+  gdb::optional<LONGEST> val_long;
+  if ((TYPE_CODE (type) == TYPE_CODE_FLT
+       && (options->format == 'o'
+          || options->format == 'x'
+          || options->format == 't'
+          || options->format == 'z'
+          || options->format == 'd'
+          || options->format == 'u'))
+      || (TYPE_CODE (type) == TYPE_CODE_RANGE
+         && TYPE_RANGE_DATA (type)->bias != 0))
+    {
+      val_long.emplace (unpack_long (type, valaddr));
+      converted_bytes.resize (TYPE_LENGTH (type));
+      store_signed_integer (converted_bytes.data (), TYPE_LENGTH (type),
+                           byte_order, *val_long);
+      valaddr = converted_bytes.data ();
     }
 
   /* Printing a non-float type as 'f' will interpret the data as if it were
@@ -468,7 +478,8 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
       {
        struct value_print_options opts = *options;
 
-       LONGEST val_long = unpack_long (type, valaddr);
+       if (!val_long.has_value ())
+         val_long.emplace (unpack_long (type, valaddr));
 
        opts.format = 0;
        if (TYPE_UNSIGNED (type))
@@ -476,15 +487,15 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
        else
          type = builtin_type (gdbarch)->builtin_true_char;
 
-       value_print (value_from_longest (type, val_long), stream, &opts);
+       value_print (value_from_longest (type, *val_long), stream, &opts);
       }
       break;
 
     case 'a':
       {
-       CORE_ADDR addr = unpack_pointer (type, valaddr);
-
-       print_address (gdbarch, addr, stream);
+       if (!val_long.has_value ())
+         val_long.emplace (unpack_long (type, valaddr));
+       print_address (gdbarch, *val_long, stream);
       }
       break;
 
@@ -528,8 +539,8 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
   int offset = 0;
   int line = 0;
 
-  if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset,
-                             &filename, &line, &unmapped))
+  if (build_address_symbolic (gdbarch, addr, do_demangle, false, &name,
+                              &offset, &filename, &line, &unmapped))
     return 0;
 
   fputs_filtered (leadin, stream);
@@ -539,7 +550,7 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
     fputs_filtered ("<", stream);
   fputs_styled (name.c_str (), function_name_style.style (), stream);
   if (offset != 0)
-    fprintf_filtered (stream, "+%u", (unsigned int) offset);
+    fprintf_filtered (stream, "%+d", offset);
 
   /* Append source filename and line number if desired.  Give specific
      line # of this addr, if we have it; else line # of the nearest symbol.  */
@@ -563,7 +574,8 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
 int
 build_address_symbolic (struct gdbarch *gdbarch,
                        CORE_ADDR addr,  /* IN */
-                       int do_demangle, /* IN */
+                       bool do_demangle, /* IN */
+                       bool prefer_sym_over_minsym, /* IN */
                        std::string *name, /* OUT */
                        int *offset,     /* OUT */
                        std::string *filename, /* OUT */
@@ -591,8 +603,10 @@ build_address_symbolic (struct gdbarch *gdbarch,
        }
     }
 
-  /* First try to find the address in the symbol table, then
-     in the minsyms.  Take the closest one.  */
+  /* Try to find the address in both the symbol table and the minsyms. 
+     In most cases, we'll prefer to use the symbol instead of the
+     minsym.  However, there are cases (see below) where we'll choose
+     to use the minsym instead.  */
 
   /* This is defective in the sense that it only finds text symbols.  So
      really this is kind of pointless--we should make sure that the
@@ -614,9 +628,9 @@ build_address_symbolic (struct gdbarch *gdbarch,
 
       name_location = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (symbol));
       if (do_demangle || asm_demangle)
-       name_temp = SYMBOL_PRINT_NAME (symbol);
+       name_temp = symbol->print_name ();
       else
-       name_temp = SYMBOL_LINKAGE_NAME (symbol);
+       name_temp = symbol->linkage_name ();
     }
 
   if (msymbol.minsym != NULL
@@ -629,7 +643,19 @@ build_address_symbolic (struct gdbarch *gdbarch,
 
   if (msymbol.minsym != NULL)
     {
-      if (BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
+      /* Use the minsym if no symbol is found.
+      
+        Additionally, use the minsym instead of a (found) symbol if
+        the following conditions all hold:
+          1) The prefer_sym_over_minsym flag is false.
+          2) The minsym address is identical to that of the address under
+             consideration.
+          3) The symbol address is not identical to that of the address
+             under consideration.  */
+      if (symbol == NULL ||
+           (!prefer_sym_over_minsym
+           && BMSYMBOL_VALUE_ADDRESS (msymbol) == addr
+           && name_location != addr))
        {
          /* If this is a function (i.e. a code address), strip out any
             non-address bits.  For instance, display a pointer to the
@@ -642,14 +668,12 @@ build_address_symbolic (struct gdbarch *gdbarch,
              || MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
            addr = gdbarch_addr_bits_remove (gdbarch, addr);
 
-         /* The msymbol is closer to the address than the symbol;
-            use the msymbol instead.  */
          symbol = 0;
          name_location = BMSYMBOL_VALUE_ADDRESS (msymbol);
          if (do_demangle || asm_demangle)
-           name_temp = MSYMBOL_PRINT_NAME (msymbol.minsym);
+           name_temp = msymbol.minsym->print_name ();
          else
-           name_temp = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
+           name_temp = msymbol.minsym->linkage_name ();
        }
     }
   if (symbol == NULL && msymbol.minsym == NULL)
@@ -666,7 +690,7 @@ build_address_symbolic (struct gdbarch *gdbarch,
       && name_location + max_symbolic_offset > name_location)
     return 1;
 
-  *offset = addr - name_location;
+  *offset = (LONGEST) addr - name_location;
 
   *name = name_temp;
 
@@ -1128,6 +1152,9 @@ print_command_parse_format (const char **expp, const char *cmdname,
 {
   const char *exp = *expp;
 
+  /* opts->raw value might already have been set by 'set print raw-values'
+     or by using 'print -raw-values'.
+     So, do not set opts->raw to 0, only set it to 1 if /r is given.  */
   if (exp && *exp == '/')
     {
       format_data fmt;
@@ -1138,12 +1165,11 @@ print_command_parse_format (const char **expp, const char *cmdname,
       last_format = fmt.format;
 
       opts->format = fmt.format;
-      opts->raw = fmt.raw;
+      opts->raw = opts->raw || fmt.raw;
     }
   else
     {
       opts->format = 0;
-      opts->raw = 0;
     }
 
   *expp = exp;
@@ -1325,7 +1351,7 @@ info_symbol_command (const char *arg, int from_tty)
            offset = sect_addr - MSYMBOL_VALUE_ADDRESS (objfile, msymbol);
            mapped = section_is_mapped (osect) ? _("mapped") : _("unmapped");
            sec_name = osect->the_bfd_section->name;
-           msym_name = MSYMBOL_PRINT_NAME (msymbol);
+           msym_name = msymbol->print_name ();
 
            /* Don't print the offset if it is zero.
               We assume there's no need to handle i18n of "sym + offset".  */
@@ -1341,7 +1367,7 @@ info_symbol_command (const char *arg, int from_tty)
            gdb_assert (osect->objfile && objfile_name (osect->objfile));
            obj_name = objfile_name (osect->objfile);
 
-           if (MULTI_OBJFILE_P ())
+           if (current_program_space->multi_objfile_p ())
              if (pc_in_unmapped_range (addr, osect))
                if (section_is_overlay (osect))
                  printf_filtered (_("%s in load address range of "
@@ -1448,7 +1474,7 @@ info_address_command (const char *exp, int from_tty)
     }
 
   printf_filtered ("Symbol \"");
-  fprintf_symbol_filtered (gdb_stdout, SYMBOL_PRINT_NAME (sym),
+  fprintf_symbol_filtered (gdb_stdout, sym->print_name (),
                           current_language->la_language, DMGL_ANSI);
   printf_filtered ("\" is ");
   val = SYMBOL_VALUE (sym);
@@ -1568,7 +1594,7 @@ info_address_command (const char *exp, int from_tty)
       {
        struct bound_minimal_symbol msym;
 
-       msym = lookup_bound_minimal_symbol (SYMBOL_LINKAGE_NAME (sym));
+       msym = lookup_bound_minimal_symbol (sym->linkage_name ());
        if (msym.minsym == NULL)
          printf_filtered ("unresolved");
        else
@@ -1922,7 +1948,8 @@ do_one_display (struct display *d)
   if (d->block)
     {
       if (d->pspace == current_program_space)
-       within_current_scope = contained_in (get_selected_block (0), d->block);
+       within_current_scope = contained_in (get_selected_block (0), d->block,
+                                            true);
       else
        within_current_scope = 0;
     }
@@ -1976,8 +2003,9 @@ do_one_display (struct display *d)
        }
       catch (const gdb_exception_error &ex)
        {
-         fprintf_filtered (gdb_stdout, _("<error: %s>\n"),
-                           ex.what ());
+         fprintf_filtered (gdb_stdout, _("%p[<error: %s>%p]\n"),
+                           metadata_style.style ().ptr (), ex.what (),
+                           nullptr);
        }
     }
   else
@@ -2010,7 +2038,8 @@ do_one_display (struct display *d)
        }
       catch (const gdb_exception_error &ex)
        {
-         fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.what ());
+         fprintf_styled (gdb_stdout, metadata_style.style (),
+                         _("<error: %s>"), ex.what ());
        }
 
       printf_filtered ("\n");
@@ -2084,7 +2113,7 @@ Num Enb Expression\n"));
       else if (d->format.format)
        printf_filtered ("/%c ", d->format.format);
       puts_filtered (d->exp_string);
-      if (d->block && !contained_in (get_selected_block (0), d->block))
+      if (d->block && !contained_in (get_selected_block (0), d->block, true))
        printf_filtered (_(" (cannot be evaluated in the current context)"));
       printf_filtered ("\n");
     }
@@ -2099,7 +2128,7 @@ do_enable_disable_display (struct display *d, void *data)
   d->enabled_p = *(int *) data;
 }
 
-/* Implamentation of both the "disable display" and "enable display"
+/* Implementation of both the "disable display" and "enable display"
    commands.  ENABLE decides what to do.  */
 
 static void
@@ -2187,11 +2216,10 @@ print_variable_and_value (const char *name, struct symbol *var,
 {
 
   if (!name)
-    name = SYMBOL_PRINT_NAME (var);
+    name = var->print_name ();
 
-  fputs_filtered (n_spaces (2 * indent), stream);
-  fputs_styled (name, variable_name_style.style (), stream);
-  fputs_filtered (" = ", stream);
+  fprintf_filtered (stream, "%s%ps = ", n_spaces (2 * indent),
+                   styled_string (variable_name_style.style (), name));
 
   try
     {
@@ -2213,8 +2241,9 @@ print_variable_and_value (const char *name, struct symbol *var,
     }
   catch (const gdb_exception_error &except)
     {
-      fprintf_filtered (stream, "<error reading variable %s (%s)>", name,
-                       except.what ());
+      fprintf_styled (stream, metadata_style.style (),
+                     "<error reading variable %s (%s)>", name,
+                     except.what ());
     }
 
   fprintf_filtered (stream, "\n");
@@ -2222,42 +2251,64 @@ print_variable_and_value (const char *name, struct symbol *var,
 
 /* Subroutine of ui_printf to simplify it.
    Print VALUE to STREAM using FORMAT.
-   VALUE is a C-style string on the target.  */
+   VALUE is a C-style string either on the target or
+   in a GDB internal variable.  */
 
 static void
 printf_c_string (struct ui_file *stream, const char *format,
                 struct value *value)
 {
-  gdb_byte *str;
-  CORE_ADDR tem;
-  int j;
+  const gdb_byte *str;
 
-  tem = value_as_address (value);
-  if (tem == 0)
+  if (VALUE_LVAL (value) == lval_internalvar
+      && c_is_string_type_p (value_type (value)))
     {
-      DIAGNOSTIC_PUSH
-      DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
-      fprintf_filtered (stream, format, "(null)");
-      DIAGNOSTIC_POP
-      return;
-    }
+      size_t len = TYPE_LENGTH (value_type (value));
 
-  /* This is a %s argument.  Find the length of the string.  */
-  for (j = 0;; j++)
-    {
-      gdb_byte c;
+      /* Copy the internal var value to TEM_STR and append a terminating null
+        character.  This protects against corrupted C-style strings that lack
+        the terminating null char.  It also allows Ada-style strings (not
+        null terminated) to be printed without problems.  */
+      gdb_byte *tem_str = (gdb_byte *) alloca (len + 1);
 
-      QUIT;
-      read_memory (tem + j, &c, 1);
-      if (c == 0)
-       break;
+      memcpy (tem_str, value_contents (value), len);
+      tem_str [len] = 0;
+      str = tem_str;
     }
+  else
+    {
+      CORE_ADDR tem = value_as_address (value);;
+
+      if (tem == 0)
+       {
+         DIAGNOSTIC_PUSH
+         DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+         fprintf_filtered (stream, format, "(null)");
+         DIAGNOSTIC_POP
+         return;
+       }
 
-  /* Copy the string contents into a string inside GDB.  */
-  str = (gdb_byte *) alloca (j + 1);
-  if (j != 0)
-    read_memory (tem, str, j);
-  str[j] = 0;
+      /* This is a %s argument.  Find the length of the string.  */
+      size_t len;
+
+      for (len = 0;; len++)
+       {
+         gdb_byte c;
+
+         QUIT;
+         read_memory (tem + len, &c, 1);
+         if (c == 0)
+           break;
+       }
+
+      /* Copy the string contents into a string inside GDB.  */
+      gdb_byte *tem_str = (gdb_byte *) alloca (len + 1);
+
+      if (len != 0)
+       read_memory (tem, tem_str, len);
+      tem_str[len] = 0;
+      str = tem_str;
+    }
 
   DIAGNOSTIC_PUSH
   DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
@@ -2267,52 +2318,65 @@ printf_c_string (struct ui_file *stream, const char *format,
 
 /* Subroutine of ui_printf to simplify it.
    Print VALUE to STREAM using FORMAT.
-   VALUE is a wide C-style string on the target.  */
+   VALUE is a wide C-style string on the target or
+   in a GDB internal variable.  */
 
 static void
 printf_wide_c_string (struct ui_file *stream, const char *format,
                      struct value *value)
 {
-  gdb_byte *str;
-  CORE_ADDR tem;
-  int j;
+  const gdb_byte *str;
+  size_t len;
   struct gdbarch *gdbarch = get_type_arch (value_type (value));
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct type *wctype = lookup_typename (current_language, gdbarch,
+  struct type *wctype = lookup_typename (current_language,
                                         "wchar_t", NULL, 0);
   int wcwidth = TYPE_LENGTH (wctype);
-  gdb_byte *buf = (gdb_byte *) alloca (wcwidth);
 
-  tem = value_as_address (value);
-  if (tem == 0)
+  if (VALUE_LVAL (value) == lval_internalvar
+      && c_is_string_type_p (value_type (value)))
     {
-      DIAGNOSTIC_PUSH
-      DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
-      fprintf_filtered (stream, format, "(null)");
-      DIAGNOSTIC_POP
-      return;
+      str = value_contents (value);
+      len = TYPE_LENGTH (value_type (value));
     }
-
-  /* This is a %s argument.  Find the length of the string.  */
-  for (j = 0;; j += wcwidth)
+  else
     {
-      QUIT;
-      read_memory (tem + j, buf, wcwidth);
-      if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0)
-       break;
-    }
+      CORE_ADDR tem = value_as_address (value);
+
+      if (tem == 0)
+       {
+         DIAGNOSTIC_PUSH
+         DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+         fprintf_filtered (stream, format, "(null)");
+         DIAGNOSTIC_POP
+         return;
+       }
+
+      /* This is a %s argument.  Find the length of the string.  */
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+      gdb_byte *buf = (gdb_byte *) alloca (wcwidth);
+
+      for (len = 0;; len += wcwidth)
+       {
+         QUIT;
+         read_memory (tem + len, 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);
+      /* Copy the string contents into a string inside GDB.  */
+      gdb_byte *tem_str = (gdb_byte *) alloca (len + wcwidth);
+
+      if (len != 0)
+       read_memory (tem, tem_str, len);
+      memset (&tem_str[len], 0, wcwidth);
+      str = tem_str;
+    }
 
   auto_obstack output;
 
   convert_between_encodings (target_wide_charset (gdbarch),
                             host_charset (),
-                            str, j, wcwidth,
+                            str, len, wcwidth,
                             &output, translit_char);
   obstack_grow_str0 (&output, "");
 
@@ -2539,7 +2603,7 @@ ui_printf (const char *arg, struct ui_file *stream)
            {
              struct gdbarch *gdbarch
                = get_type_arch (value_type (val_args[i]));
-             struct type *wctype = lookup_typename (current_language, gdbarch,
+             struct type *wctype = lookup_typename (current_language,
                                                     "wchar_t", NULL, 0);
              struct type *valtype;
              const gdb_byte *bytes;
@@ -2595,6 +2659,16 @@ ui_printf (const char *arg, struct ui_file *stream)
            {
              long val = value_as_long (val_args[i]);
 
+             DIAGNOSTIC_PUSH
+             DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
+              fprintf_filtered (stream, current_substring, val);
+             DIAGNOSTIC_POP
+             break;
+           }
+         case size_t_arg:
+           {
+             size_t val = value_as_long (val_args[i]);
+
              DIAGNOSTIC_PUSH
              DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
               fprintf_filtered (stream, current_substring, val);
@@ -2751,7 +2825,7 @@ Usage: output EXP\n\
 This is useful in user-defined commands."));
 
   add_prefix_cmd ("set", class_vars, set_command, _("\
-Evaluate expression EXP and assign result to variable VAR\n\
+Evaluate expression EXP and assign result to variable VAR.\n\
 Usage: set VAR = EXP\n\
 This uses assignment syntax appropriate for the current language\n\
 (VAR = EXP or VAR := EXP for example).\n\
@@ -2765,7 +2839,7 @@ You can see these environment settings with the \"show\" command."),
                  &setlist, "set ", 1, &cmdlist);
   if (dbx_commands)
     add_com ("assign", class_vars, set_command, _("\
-Evaluate expression EXP and assign result to variable VAR\n\
+Evaluate expression EXP and assign result to variable VAR.\n\
 Usage: assign VAR = EXP\n\
 This uses assignment syntax appropriate for the current language\n\
 (VAR = EXP or VAR := EXP for example).\n\
@@ -2786,7 +2860,7 @@ history, if it is not void."));
   set_cmd_completer_handle_brkchars (c, print_command_completer);
 
   add_cmd ("variable", class_vars, set_command, _("\
-Evaluate expression EXP and assign result to variable VAR\n\
+Evaluate expression EXP and assign result to variable VAR.\n\
 Usage: set variable VAR = EXP\n\
 This uses assignment syntax appropriate for the current language\n\
 (VAR = EXP or VAR := EXP for example).\n\
@@ -2799,12 +2873,13 @@ This may usually be abbreviated to simply \"set\"."),
 
   const auto print_opts = make_value_print_options_def_group (nullptr);
 
-  static const std::string print_help = gdb::option::build_help (N_("\
+  static const std::string print_help = gdb::option::build_help (_("\
 Print value of expression EXP.\n\
 Usage: print [[OPTION]... --] [/FMT] [EXP]\n\
 \n\
 Options:\n\
-%OPTIONS%\
+%OPTIONS%\n\
+\n\
 Note: because this command accepts arbitrary expressions, if you\n\
 specify any command option, you must use a double dash (\"--\")\n\
 to mark the end of option processing.  E.g.: \"print -o -- myobj\".\n\
This page took 0.035216 seconds and 4 git commands to generate.