* 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:
parent
b21991b00c
commit
6309237547
10 changed files with 128 additions and 27 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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" ""
|
||||
|
|
|
@ -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"
|
||||
|
|
91
gdb/valops.c
91
gdb/valops.c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue