* 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.

	* 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.
This commit is contained in:
Daniel Jacobowitz 2008-03-21 15:02:38 +00:00
parent b21991b00c
commit 6309237547
10 changed files with 128 additions and 27 deletions

View file

@ -1,3 +1,18 @@
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.

View file

@ -1,3 +1,7 @@
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

View file

@ -5597,8 +5597,10 @@ you compiled your program to include this information; see
@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

View file

@ -2204,14 +2204,14 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
{
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);
}

View file

@ -111,6 +111,12 @@ value_arg_coerce (struct value *arg, struct type *param_type,
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:

View file

@ -1,3 +1,12 @@
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,

View file

@ -651,7 +651,7 @@ proc test_print_array_constants {} {
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 {} {
@ -735,11 +735,19 @@ gdb_start
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" ""

View file

@ -638,7 +638,7 @@ if [runto_main] then {
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"

View file

@ -600,9 +600,18 @@ value_assign (struct value *toval, struct value *fromval)
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
@ -852,6 +861,50 @@ value_of_variable (struct symbol *var, struct block *b)
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.
@ -881,6 +934,11 @@ value_coerce_array (struct value *arg1)
{
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."));
@ -926,6 +984,10 @@ value_addr (struct value *arg1)
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."));
@ -1016,7 +1078,7 @@ value_ind (struct value *arg1)
return 0; /* For lint -- never reached. */
}
/* 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.
@ -1074,24 +1136,15 @@ value_array (int lowbound, int highbound, struct value **elemvec)
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

View file

@ -332,6 +332,10 @@ extern struct value *value_add (struct value *arg1, struct value *arg2);
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);