Use value_must_coerce_to_target.
* infcall.c (value_arg_coerce): Call value_coerce_to_target.
* valops.c (value_assign): Call value_coerce_to_target when
assigning to anything but internalvars. Leave GDB-side arrays
as arrays when assigning to internalvars.
(value_must_coerce_to_target, value_coerce_to_target): New.
(value_coerce_array, value_addr): Call value_coerce_to_target.
(value_array): Create the array in GDB's memory instead of
the inferior's.
* value.h (value_must_coerce_to_target, value_coerce_to_target):
Declare.
* gdb.texinfo (Expressions): Update description of malloced arrays.
* gdb.base/printcmds.exp (test_print_array_constants): Do not expect
*& to work on created array elements.
(Top level): Test print $pc with a file. Test string operations
without a target.
* gdb.base/ptype.exp: Do not expect *& to work on created array
elements.
+2008-03-21 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * eval.c (evaluate_subexp_for_address): Clarify error message.
+ Use value_must_coerce_to_target.
+ * infcall.c (value_arg_coerce): Call value_coerce_to_target.
+ * valops.c (value_assign): Call value_coerce_to_target when
+ assigning to anything but internalvars. Leave GDB-side arrays
+ as arrays when assigning to internalvars.
+ (value_must_coerce_to_target, value_coerce_to_target): New.
+ (value_coerce_array, value_addr): Call value_coerce_to_target.
+ (value_array): Create the array in GDB's memory instead of
+ the inferior's.
+ * value.h (value_must_coerce_to_target, value_coerce_to_target):
+ Declare.
+
2008-03-21 Daniel Jacobowitz <dan@codesourcery.com>
* top.c (quit_confirm): Warn that we will kill the program.
+2008-03-21 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * gdb.texinfo (Expressions): Update description of malloced arrays.
+
2008-03-15 Vladimir Prus <vladimir@codesourcery.com>
* gdb.texinfo (Thread Commands): Document
@cindex arrays in expressions
@value{GDBN} supports array constants in expressions input by
the user. The syntax is @{@var{element}, @var{element}@dots{}@}. For example,
-you can use the command @code{print @{1, 2, 3@}} to build up an array in
-memory that is @code{malloc}ed in the target program.
+you can use the command @code{print @{1, 2, 3@}} to create an array
+of three integers. If you pass an array to a function or assign it
+to a program variable, @value{GDBN} copies the array to memory that
+is @code{malloc}ed in the target program.
Because C is so widespread, most of the expressions shown in examples in
this manual are in C. @xref{Languages, , Using @value{GDBN} with Different
{
struct type *type = check_typedef (value_type (x));
- if (VALUE_LVAL (x) == lval_memory)
+ if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
return value_zero (lookup_pointer_type (value_type (x)),
not_lval);
else if (TYPE_CODE (type) == TYPE_CODE_REF)
return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
not_lval);
else
- error (_("Attempt to take address of non-lval"));
+ error (_("Attempt to take address of value not located in memory."));
}
return value_addr (x);
}
if (current_language->la_language == language_ada)
arg = ada_convert_actual (arg, type, sp);
+ /* Force the value to the target if we will need its address. At
+ this point, we could allocate arguments on the stack instead of
+ calling malloc if we knew that their addresses would not be
+ saved by the called function. */
+ arg = value_coerce_to_target (arg);
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_REF:
+2008-03-21 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * gdb.base/printcmds.exp (test_print_array_constants): Do not expect
+ *& to work on created array elements.
+ (Top level): Test print $pc with a file. Test string operations
+ without a target.
+ * gdb.base/ptype.exp: Do not expect *& to work on created array
+ elements.
+
2008-03-21 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.threads/killed.exp, gdb.threads/manythreads.exp,
gdb_test_escape_braces "print {(long)0,(long)1,(long)2}" " = {0, 1, 2}"
gdb_test_escape_braces "print {{0,1,2},{3,4,5}}" " = {{0, 1, 2}, {3, 4, 5}}"
gdb_test "print {4,5,6}\[2\]" " = 6"
- gdb_test "print *&{4,5,6}\[1\]" " = 5"
+ gdb_test "print *&{4,5,6}\[1\]" "Attempt to take address of value not located in memory."
}
proc test_printf {} {
gdb_reinitialize_dir $srcdir/$subdir
gdb_test "print \$pc" "No registers\\."
-# FIXME: should also test "print $pc" when there is an execfile but no
-# remote debugging target, process or corefile.
+
+# Some simple operations on strings should work even without a target
+# (and therefore without calling malloc).
+gdb_test "print \"abc\"" " = \"abc\""
+gdb_test "print sizeof (\"abc\")" " = 4"
+gdb_test "ptype \"abc\"" " = char \\\[4\\\]"
+gdb_test "print \$cvar = \"abc\"" " = \"abc\""
+gdb_test "print sizeof (\$cvar)" " = 4"
gdb_load ${binfile}
+gdb_test "print \$pc" "No registers\\." "print \$pc (with file)"
+
gdb_test "set print sevenbit-strings" ""
gdb_test "set print address off" ""
gdb_test "set width 0" ""
gdb_test "ptype {(float)0,(float)1,(float)2}" "type = float \\\[3\\\]"
gdb_test "ptype {{0,1,2},{3,4,5}}" "type = int \\\[2\\\]\\\[3\\\]"
gdb_test "ptype {4,5,6}\[2\]" "type = int"
- gdb_test "ptype *&{4,5,6}\[1\]" "type = int"
+ gdb_test "ptype *&{4,5,6}\[1\]" "Attempt to take address of value not located in memory."
# Test ptype of user register
gdb_test "ptype \$pc" "void \\(\\*\\)\\(\\)" "ptype \$pc"
type = value_type (toval);
if (VALUE_LVAL (toval) != lval_internalvar)
- fromval = value_cast (type, fromval);
+ {
+ toval = value_coerce_to_target (toval);
+ fromval = value_cast (type, fromval);
+ }
else
- fromval = coerce_array (fromval);
+ {
+ /* Coerce arrays and functions to pointers, except for arrays
+ which only live in GDB's storage. */
+ if (!value_must_coerce_to_target (fromval))
+ fromval = coerce_array (fromval);
+ }
+
CHECK_TYPEDEF (type);
/* Since modifying a register can trash the frame chain, and
return val;
}
+/* Return one if VAL does not live in target memory, but should in order
+ to operate on it. Otherwise return zero. */
+
+int
+value_must_coerce_to_target (struct value *val)
+{
+ struct type *valtype;
+
+ /* The only lval kinds which do not live in target memory. */
+ if (VALUE_LVAL (val) != not_lval
+ && VALUE_LVAL (val) != lval_internalvar)
+ return 0;
+
+ valtype = check_typedef (value_type (val));
+
+ switch (TYPE_CODE (valtype))
+ {
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_STRING:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Make sure that VAL lives in target memory if it's supposed to. For instance,
+ strings are constructed as character arrays in GDB's storage, and this
+ function copies them to the target. */
+
+struct value *
+value_coerce_to_target (struct value *val)
+{
+ LONGEST length;
+ CORE_ADDR addr;
+
+ if (!value_must_coerce_to_target (val))
+ return val;
+
+ length = TYPE_LENGTH (check_typedef (value_type (val)));
+ addr = allocate_space_in_inferior (length);
+ write_memory (addr, value_contents (val), length);
+ return value_at_lazy (value_type (val), addr);
+}
+
/* Given a value which is an array, return a value which is a pointer
to its first element, regardless of whether or not the array has a
nonzero lower bound.
{
struct type *type = check_typedef (value_type (arg1));
+ /* If the user tries to do something requiring a pointer with an
+ array that has not yet been pushed to the target, then this would
+ be a good time to do so. */
+ arg1 = value_coerce_to_target (arg1);
+
if (VALUE_LVAL (arg1) != lval_memory)
error (_("Attempt to take address of value not located in memory."));
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
return value_coerce_function (arg1);
+ /* If this is an array that has not yet been pushed to the target,
+ then this would be a good time to force it to memory. */
+ arg1 = value_coerce_to_target (arg1);
+
if (VALUE_LVAL (arg1) != lval_memory)
error (_("Attempt to take address of value not located in memory."));
return 0; /* For lint -- never reached. */
}
\f
-/* Create a value for an array by allocating space in the inferior,
+/* Create a value for an array by allocating space in GDB, copying
copying the data into that space, and then setting up an array
value.
return val;
}
- /* Allocate space to store the array in the inferior, and then
- initialize it by copying in each element. FIXME: Is it worth it
- to create a local buffer in which to collect each value and then
- write all the bytes in one operation? */
+ /* Allocate space to store the array, and then initialize it by
+ copying in each element. */
- addr = allocate_space_in_inferior (nelem * typelength);
+ val = allocate_value (arraytype);
for (idx = 0; idx < nelem; idx++)
- {
- write_memory (addr + (idx * typelength),
- value_contents_all (elemvec[idx]),
- typelength);
- }
-
- /* Create the array type and set up an array value to be evaluated
- lazily. */
-
- val = value_at_lazy (arraytype, addr);
- return (val);
+ memcpy (value_contents_writeable (val) + (idx * typelength),
+ value_contents_all (elemvec[idx]),
+ typelength);
+ return val;
}
/* Create a value for a string constant by allocating space in the
extern struct value *value_sub (struct value *arg1, struct value *arg2);
+extern int value_must_coerce_to_target (struct value *arg1);
+
+extern struct value *value_coerce_to_target (struct value *arg1);
+
extern struct value *value_coerce_array (struct value *arg1);
extern struct value *value_coerce_function (struct value *arg1);