summaryrefslogtreecommitdiff
path: root/gdb/value.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/value.c')
-rw-r--r--gdb/value.c122
1 files changed, 71 insertions, 51 deletions
diff --git a/gdb/value.c b/gdb/value.c
index 37c949f0853..022fca91a42 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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
@@ -1703,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;
@@ -1713,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;
@@ -1725,13 +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))
- copy (value_contents_all_raw (arg),
- value_contents_all_raw (val));
-
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)
{
@@ -1909,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)
{
@@ -1937,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. */
@@ -2441,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;
}
@@ -2626,7 +2636,7 @@ show_convenience (const char *ignore, int from_tty)
{
varseen = 1;
}
- printf_filtered (("$%s = "), var->name);
+ gdb_printf (("$%s = "), var->name);
try
{
@@ -2641,7 +2651,7 @@ show_convenience (const char *ignore, int from_tty)
_("<error: %s>"), ex.what ());
}
- printf_filtered (("\n"));
+ gdb_printf (("\n"));
}
if (!varseen)
{
@@ -2649,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_filtered (_("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"));
}
}
@@ -2976,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);
@@ -3163,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;
@@ -3179,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
{
@@ -3190,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 ()));
}
@@ -3997,15 +4002,15 @@ 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
@@ -4014,20 +4019,20 @@ value_fetch_lazy_register (struct value *val)
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 ());
@@ -4268,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 */
@@ -4352,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
}