ODR warnings for "struct insn_info"
[binutils-gdb.git] / gdb / value.c
index 998bec321a2b0e566b0dba2c0d9fbf2d14535c17..022fca91a42a8b4d5bccc745b62e642aea8a02ed 100644 (file)
@@ -1,6 +1,6 @@
 /* Low level packing and unpacking of values for GDB, the GNU Debugger.
 
-   Copyright (C) 1986-2021 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -343,8 +343,10 @@ struct value
   LONGEST embedded_offset = 0;
   LONGEST pointed_to_offset = 0;
 
-  /* Actual contents of the value.  Target byte-order.  NULL or not
-     valid if lazy is nonzero.  */
+  /* Actual contents of the value.  Target byte-order.
+
+     May be nullptr if the value is lazy or is entirely optimized out.
+     Guaranteed to be non-nullptr otherwise.  */
   gdb::unique_xmalloc_ptr<gdb_byte> contents;
 
   /* Unavailable ranges in CONTENTS.  We mark unavailable ranges,
@@ -989,10 +991,10 @@ show_max_value_size (struct ui_file *file, int from_tty,
                     struct cmd_list_element *c, const char *value)
 {
   if (max_value_size == -1)
-    fprintf_filtered (file, _("Maximum value size is unlimited.\n"));
+    gdb_printf (file, _("Maximum value size is unlimited.\n"));
   else
-    fprintf_filtered (file, _("Maximum value size is %d bytes.\n"),
-                     max_value_size);
+    gdb_printf (file, _("Maximum value size is %d bytes.\n"),
+               max_value_size);
 }
 
 /* Called before we attempt to allocate or reallocate a buffer for the
@@ -1164,7 +1166,7 @@ value_contents_all_raw (struct value *value)
 {
   allocate_value_contents (value);
 
-  ULONGEST length = TYPE_LENGTH (value_type (value));
+  ULONGEST length = TYPE_LENGTH (value_enclosing_type (value));
   return gdb::make_array_view (value->contents.get (), length);
 }
 
@@ -1221,7 +1223,7 @@ value_actual_type (struct value *value, int resolve_simple_types,
 void
 error_value_optimized_out (void)
 {
-  error (_("value has been optimized out"));
+  throw_error (OPTIMIZED_OUT_ERROR, _("value has been optimized out"));
 }
 
 static void
@@ -1230,7 +1232,8 @@ require_not_optimized_out (const struct value *value)
   if (!value->optimized_out.empty ())
     {
       if (value->lval == lval_register)
-       error (_("register has not been saved in frame"));
+       throw_error (OPTIMIZED_OUT_ERROR,
+                    _("register has not been saved in frame"));
       else
        error_value_optimized_out ();
     }
@@ -1249,7 +1252,7 @@ value_contents_for_printing (struct value *value)
   if (value->lazy)
     value_fetch_lazy (value);
 
-  ULONGEST length = TYPE_LENGTH (value_type (value));
+  ULONGEST length = TYPE_LENGTH (value_enclosing_type (value));
   return gdb::make_array_view (value->contents.get (), length);
 }
 
@@ -1258,7 +1261,7 @@ value_contents_for_printing_const (const struct value *value)
 {
   gdb_assert (!value->lazy);
 
-  ULONGEST length = TYPE_LENGTH (value_type (value));
+  ULONGEST length = TYPE_LENGTH (value_enclosing_type (value));
   return gdb::make_array_view (value->contents.get (), length);
 }
 
@@ -1343,9 +1346,13 @@ value_contents_copy_raw (struct value *dst, LONGEST dst_offset,
                                             TARGET_CHAR_BIT * length));
 
   /* Copy the data.  */
-  memcpy (value_contents_all_raw (dst).data () + dst_offset * unit_size,
-         value_contents_all_raw (src).data () + src_offset * unit_size,
-         length * unit_size);
+  gdb::array_view<gdb_byte> dst_contents
+    = value_contents_all_raw (dst).slice (dst_offset * unit_size,
+                                         length * unit_size);
+  gdb::array_view<const gdb_byte> src_contents
+    = value_contents_all_raw (src).slice (src_offset * unit_size,
+                                         length * unit_size);
+  copy (src_contents, dst_contents);
 
   /* Copy the meta-data, adjusted.  */
   src_bit_offset = src_offset * unit_size * HOST_CHAR_BIT;
@@ -1698,7 +1705,7 @@ value_release_to_mark (const struct value *mark)
    but it's a different block of storage.  */
 
 struct value *
-value_copy (struct value *arg)
+value_copy (const value *arg)
 {
   struct type *encl_type = value_enclosing_type (arg);
   struct value *val;
@@ -1708,7 +1715,7 @@ value_copy (struct value *arg)
   else
     val = allocate_value (encl_type);
   val->type = arg->type;
-  VALUE_LVAL (val) = VALUE_LVAL (arg);
+  VALUE_LVAL (val) = arg->lval;
   val->location = arg->location;
   val->offset = arg->offset;
   val->bitpos = arg->bitpos;
@@ -1720,15 +1727,18 @@ value_copy (struct value *arg)
   val->stack = arg->stack;
   val->is_zero = arg->is_zero;
   val->initialized = arg->initialized;
-  if (!value_lazy (val))
-    {
-      memcpy (value_contents_all_raw (val).data (),
-             value_contents_all_raw (arg).data (),
-             TYPE_LENGTH (value_enclosing_type (arg)));
-
-    }
   val->unavailable = arg->unavailable;
   val->optimized_out = arg->optimized_out;
+
+  if (!value_lazy (val) && !value_entirely_optimized_out (val))
+    {
+      gdb_assert (arg->contents != nullptr);
+      ULONGEST length = TYPE_LENGTH (value_enclosing_type (arg));
+      const auto &arg_view
+       = gdb::make_array_view (arg->contents.get (), length);
+      copy (arg_view, value_contents_all_raw (val));
+    }
+
   val->parent = arg->parent;
   if (VALUE_LVAL (val) == lval_computed)
     {
@@ -1771,9 +1781,7 @@ value_non_lval (struct value *arg)
       struct type *enc_type = value_enclosing_type (arg);
       struct value *val = allocate_value (enc_type);
 
-      memcpy (value_contents_all_raw (val).data (),
-             value_contents_all (arg).data (),
-             TYPE_LENGTH (enc_type));
+      copy (value_contents_all (arg), value_contents_all_raw (val));
       val->type = arg->type;
       set_value_embedded_offset (val, value_embedded_offset (arg));
       set_value_pointed_to_offset (val, value_pointed_to_offset (arg));
@@ -1908,6 +1916,14 @@ access_value_history (int num)
   return value_copy (value_history[absnum].get ());
 }
 
+/* See value.h.  */
+
+ULONGEST
+value_history_count ()
+{
+  return value_history.size ();
+}
+
 static void
 show_values (const char *num_exp, int from_tty)
 {
@@ -1936,10 +1952,10 @@ show_values (const char *num_exp, int from_tty)
       struct value_print_options opts;
 
       val = access_value_history (i);
-      printf_filtered (("$%d = "), i);
+      gdb_printf (("$%d = "), i);
       get_user_print_options (&opts);
       value_print (val, gdb_stdout, &opts);
-      printf_filtered (("\n"));
+      gdb_printf (("\n"));
     }
 
   /* The next "show values +" should start after what we just printed.  */
@@ -2440,11 +2456,6 @@ clear_internalvar (struct internalvar *var)
       xfree (var->u.string);
       break;
 
-    case INTERNALVAR_MAKE_VALUE:
-      if (var->u.make_value.functions->destroy != NULL)
-       var->u.make_value.functions->destroy (var->u.make_value.data);
-      break;
-
     default:
       break;
     }
@@ -2625,7 +2636,7 @@ show_convenience (const char *ignore, int from_tty)
        {
          varseen = 1;
        }
-      printf_filtered (("$%s = "), var->name);
+      gdb_printf (("$%s = "), var->name);
 
       try
        {
@@ -2640,7 +2651,7 @@ show_convenience (const char *ignore, int from_tty)
                          _("<error: %s>"), ex.what ());
        }
 
-      printf_filtered (("\n"));
+      gdb_printf (("\n"));
     }
   if (!varseen)
     {
@@ -2648,11 +2659,11 @@ show_convenience (const char *ignore, int from_tty)
         The user can't create them except via Python, and if Python support
         is installed this message will never be printed ($_streq will
         exist).  */
-      printf_unfiltered (_("No debugger convenience variables now defined.\n"
-                          "Convenience variables have "
-                          "names starting with \"$\";\n"
-                          "use \"set\" as in \"set "
-                          "$foo = 5\" to define them.\n"));
+      gdb_printf (_("No debugger convenience variables now defined.\n"
+                   "Convenience variables have "
+                   "names starting with \"$\";\n"
+                   "use \"set\" as in \"set "
+                   "$foo = 5\" to define them.\n"));
     }
 }
 \f
@@ -2975,7 +2986,7 @@ value_static_field (struct type *type, int fieldno)
          if (!msym.minsym)
            retval = allocate_optimized_out_value (field_type);
          else
-           retval = value_at_lazy (field_type, BMSYMBOL_VALUE_ADDRESS (msym));
+           retval = value_at_lazy (field_type, msym.value_address ());
        }
       else
        retval = value_of_variable (sym.symbol, sym.block);
@@ -3162,13 +3173,8 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
   struct bound_minimal_symbol msym;
 
   sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0).symbol;
-  if (sym != NULL)
-    {
-      memset (&msym, 0, sizeof (msym));
-    }
-  else
+  if (sym == nullptr)
     {
-      gdb_assert (sym == NULL);
       msym = lookup_bound_minimal_symbol (physname);
       if (msym.minsym == NULL)
        return NULL;
@@ -3178,7 +3184,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
   VALUE_LVAL (v) = lval_memory;
   if (sym)
     {
-      set_value_address (v, BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)));
+      set_value_address (v, sym->value_block ()->entry_pc ());
     }
   else
     {
@@ -3189,7 +3195,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
 
       set_value_address (v,
        gdbarch_convert_from_func_ptr_addr
-          (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym),
+          (gdbarch, msym.value_address (),
            current_inferior ()->top_target ()));
     }
 
@@ -3996,37 +4002,37 @@ value_fetch_lazy_register (struct value *val)
       gdbarch = get_frame_arch (frame);
 
       string_file debug_file;
-      fprintf_unfiltered (&debug_file,
-                         "(frame=%d, regnum=%d(%s), ...) ",
-                         frame_relative_level (frame), regnum,
-                         user_reg_map_regnum_to_name (gdbarch, regnum));
+      gdb_printf (&debug_file,
+                 "(frame=%d, regnum=%d(%s), ...) ",
+                 frame_relative_level (frame), regnum,
+                 user_reg_map_regnum_to_name (gdbarch, regnum));
 
-      fprintf_unfiltered (&debug_file, "->");
+      gdb_printf (&debug_file, "->");
       if (value_optimized_out (new_val))
        {
-         fprintf_unfiltered (&debug_file, " ");
+         gdb_printf (&debug_file, " ");
          val_print_optimized_out (new_val, &debug_file);
        }
       else
        {
          int i;
-         const gdb_byte *buf = value_contents (new_val).data ();
+         gdb::array_view<const gdb_byte> buf = value_contents (new_val);
 
          if (VALUE_LVAL (new_val) == lval_register)
-           fprintf_unfiltered (&debug_file, " register=%d",
-                               VALUE_REGNUM (new_val));
+           gdb_printf (&debug_file, " register=%d",
+                       VALUE_REGNUM (new_val));
          else if (VALUE_LVAL (new_val) == lval_memory)
-           fprintf_unfiltered (&debug_file, " address=%s",
-                               paddress (gdbarch,
-                                         value_address (new_val)));
+           gdb_printf (&debug_file, " address=%s",
+                       paddress (gdbarch,
+                                 value_address (new_val)));
          else
-           fprintf_unfiltered (&debug_file, " computed");
+           gdb_printf (&debug_file, " computed");
 
-         fprintf_unfiltered (&debug_file, " bytes=");
-         fprintf_unfiltered (&debug_file, "[");
+         gdb_printf (&debug_file, " bytes=");
+         gdb_printf (&debug_file, "[");
          for (i = 0; i < register_size (gdbarch, regnum); i++)
-           fprintf_unfiltered (&debug_file, "%02x", buf[i]);
-         fprintf_unfiltered (&debug_file, "]");
+           gdb_printf (&debug_file, "%02x", buf[i]);
+         gdb_printf (&debug_file, "]");
        }
 
       frame_debug_printf ("%s", debug_file.c_str ());
@@ -4267,6 +4273,20 @@ test_insert_into_bit_range_vector ()
   }
 }
 
+static void
+test_value_copy ()
+{
+  type *type = builtin_type (current_inferior ()->gdbarch)->builtin_int;
+
+  /* Verify that we can copy an entirely optimized out value, that may not have
+     its contents allocated.  */
+  value_ref_ptr val = release_value (allocate_optimized_out_value (type));
+  value_ref_ptr copy = release_value (value_copy (val.get ()));
+
+  SELF_CHECK (value_entirely_optimized_out (val.get ()));
+  SELF_CHECK (value_entirely_optimized_out (copy.get ()));
+}
+
 } /* namespace selftests */
 #endif /* GDB_SELF_TEST */
 
@@ -4351,6 +4371,7 @@ and exceeds this limit will cause an error."),
   selftests::register_test ("ranges_contain", selftests::test_ranges_contain);
   selftests::register_test ("insert_into_bit_range_vector",
                            selftests::test_insert_into_bit_range_vector);
+  selftests::register_test ("value_copy", selftests::test_value_copy);
 #endif
 }