forked from Imagelibrary/binutils-gdb
2002-11-06 Andrew Cagney <ac131313@redhat.com>
* valops.c (value_assign): Merge lval_register case into lval_reg_frame_relative. Use frame_register and regcache_cooked_write instead of get_saved_register and write_register_bytes. After flushing the register cache, try to re-select the selected frame.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2002-11-06 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* valops.c (value_assign): Merge lval_register case into
|
||||
lval_reg_frame_relative. Use frame_register and
|
||||
regcache_cooked_write instead of get_saved_register and
|
||||
write_register_bytes. After flushing the register cache, try to
|
||||
re-select the selected frame.
|
||||
|
||||
2002-11-06 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* regcache.h (deprecated_register_valid): Rename register_valid.
|
||||
|
||||
199
gdb/valops.c
199
gdb/valops.c
@@ -630,132 +630,120 @@ value_assign (struct value *toval, struct value *fromval)
|
||||
}
|
||||
break;
|
||||
|
||||
case lval_register:
|
||||
if (VALUE_BITSIZE (toval))
|
||||
{
|
||||
char buffer[sizeof (LONGEST)];
|
||||
int len =
|
||||
REGISTER_RAW_SIZE (VALUE_REGNO (toval)) - VALUE_OFFSET (toval);
|
||||
|
||||
if (len > (int) sizeof (LONGEST))
|
||||
error ("Can't handle bitfields in registers larger than %d bits.",
|
||||
(int) sizeof (LONGEST) * HOST_CHAR_BIT);
|
||||
|
||||
if (VALUE_BITPOS (toval) + VALUE_BITSIZE (toval)
|
||||
> len * HOST_CHAR_BIT)
|
||||
/* Getting this right would involve being very careful about
|
||||
byte order. */
|
||||
error ("Can't assign to bitfields that cross register "
|
||||
"boundaries.");
|
||||
|
||||
read_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
buffer, len);
|
||||
modify_field (buffer, value_as_long (fromval),
|
||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
buffer, len);
|
||||
}
|
||||
else if (use_buffer)
|
||||
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
raw_buffer, use_buffer);
|
||||
else
|
||||
{
|
||||
/* Do any conversion necessary when storing this type to more
|
||||
than one register. */
|
||||
#ifdef REGISTER_CONVERT_FROM_TYPE
|
||||
memcpy (raw_buffer, VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
|
||||
REGISTER_CONVERT_FROM_TYPE (VALUE_REGNO (toval), type, raw_buffer);
|
||||
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
raw_buffer, TYPE_LENGTH (type));
|
||||
#else
|
||||
write_register_bytes (VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
|
||||
VALUE_CONTENTS (fromval), TYPE_LENGTH (type));
|
||||
#endif
|
||||
}
|
||||
|
||||
target_changed_event ();
|
||||
|
||||
/* Assigning to the stack pointer, frame pointer, and other
|
||||
(architecture and calling convention specific) registers may
|
||||
cause the frame cache to be out of date. We just do this
|
||||
on all assignments to registers for simplicity; I doubt the slowdown
|
||||
matters. */
|
||||
reinit_frame_cache ();
|
||||
break;
|
||||
|
||||
case lval_reg_frame_relative:
|
||||
case lval_register:
|
||||
{
|
||||
struct frame_id old_frame;
|
||||
/* value is stored in a series of registers in the frame
|
||||
specified by the structure. Copy that value out, modify
|
||||
it, and copy it back in. */
|
||||
int amount_to_copy = (VALUE_BITSIZE (toval) ? 1 : TYPE_LENGTH (type));
|
||||
int reg_size = REGISTER_RAW_SIZE (VALUE_FRAME_REGNUM (toval));
|
||||
int byte_offset = VALUE_OFFSET (toval) % reg_size;
|
||||
int reg_offset = VALUE_OFFSET (toval) / reg_size;
|
||||
int amount_copied;
|
||||
|
||||
/* Make the buffer large enough in all cases. */
|
||||
/* FIXME (alloca): Not safe for very large data types. */
|
||||
char *buffer = (char *) alloca (amount_to_copy
|
||||
+ sizeof (LONGEST)
|
||||
+ MAX_REGISTER_RAW_SIZE);
|
||||
|
||||
int amount_to_copy;
|
||||
char *buffer;
|
||||
int value_reg;
|
||||
int reg_offset;
|
||||
int byte_offset;
|
||||
int regno;
|
||||
struct frame_info *frame;
|
||||
|
||||
/* Since modifying a register can trash the frame chain, we
|
||||
save the old frame and then restore the new frame
|
||||
afterwards. */
|
||||
get_frame_id (selected_frame, &old_frame);
|
||||
|
||||
/* Figure out which frame this is in currently. */
|
||||
for (frame = get_current_frame ();
|
||||
frame && FRAME_FP (frame) != VALUE_FRAME (toval);
|
||||
frame = get_prev_frame (frame))
|
||||
;
|
||||
if (VALUE_LVAL (toval) == lval_register)
|
||||
{
|
||||
frame = get_current_frame ();
|
||||
value_reg = VALUE_REGNO (toval);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (frame = get_current_frame ();
|
||||
frame && FRAME_FP (frame) != VALUE_FRAME (toval);
|
||||
frame = get_prev_frame (frame))
|
||||
;
|
||||
value_reg = VALUE_FRAME_REGNUM (toval);
|
||||
}
|
||||
|
||||
if (!frame)
|
||||
error ("Value being assigned to is no longer active.");
|
||||
|
||||
amount_to_copy += (reg_size - amount_to_copy % reg_size);
|
||||
/* Locate the first register that falls in the value that
|
||||
needs to be transfered. Compute the offset of the value in
|
||||
that register. */
|
||||
{
|
||||
int offset;
|
||||
for (reg_offset = value_reg, offset = 0;
|
||||
offset + REGISTER_RAW_SIZE (reg_offset) <= VALUE_OFFSET (toval);
|
||||
reg_offset++);
|
||||
byte_offset = VALUE_OFFSET (toval) - offset;
|
||||
}
|
||||
|
||||
/* Copy it out. */
|
||||
for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
|
||||
amount_copied = 0);
|
||||
/* Compute the number of register aligned values that need to
|
||||
be copied. */
|
||||
if (VALUE_BITSIZE (toval))
|
||||
amount_to_copy = byte_offset + 1;
|
||||
else
|
||||
amount_to_copy = byte_offset + TYPE_LENGTH (type);
|
||||
|
||||
/* And a bounce buffer. Be slightly over generous. */
|
||||
buffer = (char *) alloca (amount_to_copy
|
||||
+ MAX_REGISTER_RAW_SIZE);
|
||||
|
||||
/* Copy it in. */
|
||||
for (regno = reg_offset, amount_copied = 0;
|
||||
amount_copied < amount_to_copy;
|
||||
amount_copied += reg_size, regno++)
|
||||
amount_copied += REGISTER_RAW_SIZE (regno), regno++)
|
||||
{
|
||||
get_saved_register (buffer + amount_copied,
|
||||
(int *) NULL, (CORE_ADDR *) NULL,
|
||||
frame, regno, (enum lval_type *) NULL);
|
||||
frame_register_read (frame, regno, buffer + amount_copied);
|
||||
}
|
||||
|
||||
|
||||
/* Modify what needs to be modified. */
|
||||
if (VALUE_BITSIZE (toval))
|
||||
modify_field (buffer + byte_offset,
|
||||
value_as_long (fromval),
|
||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||
{
|
||||
modify_field (buffer + byte_offset,
|
||||
value_as_long (fromval),
|
||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||
}
|
||||
else if (use_buffer)
|
||||
memcpy (buffer + byte_offset, raw_buffer, use_buffer);
|
||||
{
|
||||
memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
|
||||
}
|
||||
else
|
||||
memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
|
||||
TYPE_LENGTH (type));
|
||||
{
|
||||
memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
|
||||
TYPE_LENGTH (type));
|
||||
/* Do any conversion necessary when storing this type to
|
||||
more than one register. */
|
||||
#ifdef REGISTER_CONVERT_FROM_TYPE
|
||||
REGISTER_CONVERT_FROM_TYPE (value_reg, type,
|
||||
(buffer + byte_offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Copy it back. */
|
||||
for ((regno = VALUE_FRAME_REGNUM (toval) + reg_offset,
|
||||
amount_copied = 0);
|
||||
/* Copy it out. */
|
||||
for (regno = reg_offset, amount_copied = 0;
|
||||
amount_copied < amount_to_copy;
|
||||
amount_copied += reg_size, regno++)
|
||||
amount_copied += REGISTER_RAW_SIZE (regno), regno++)
|
||||
{
|
||||
enum lval_type lval;
|
||||
CORE_ADDR addr;
|
||||
int optim;
|
||||
|
||||
int realnum;
|
||||
|
||||
/* Just find out where to put it. */
|
||||
get_saved_register ((char *) NULL,
|
||||
&optim, &addr, frame, regno, &lval);
|
||||
|
||||
frame_register (frame, regno, &optim, &lval, &addr, &realnum,
|
||||
NULL);
|
||||
|
||||
if (optim)
|
||||
error ("Attempt to assign to a value that was optimized out.");
|
||||
if (lval == lval_memory)
|
||||
write_memory (addr, buffer + amount_copied, reg_size);
|
||||
write_memory (addr, buffer + amount_copied,
|
||||
REGISTER_RAW_SIZE (regno));
|
||||
else if (lval == lval_register)
|
||||
write_register_bytes (addr, buffer + amount_copied, reg_size);
|
||||
regcache_cooked_write (current_regcache, realnum,
|
||||
(buffer + amount_copied));
|
||||
else
|
||||
error ("Attempt to assign to an unmodifiable value.");
|
||||
}
|
||||
@@ -763,10 +751,31 @@ value_assign (struct value *toval, struct value *fromval)
|
||||
if (register_changed_hook)
|
||||
register_changed_hook (-1);
|
||||
target_changed_event ();
|
||||
|
||||
/* Assigning to the stack pointer, frame pointer, and other
|
||||
(architecture and calling convention specific) registers
|
||||
may cause the frame cache to be out of date. We just do
|
||||
this on all assignments to registers for simplicity; I
|
||||
doubt the slowdown matters. */
|
||||
reinit_frame_cache ();
|
||||
|
||||
/* Having destoroyed the frame cache, restore the selected
|
||||
frame. */
|
||||
/* FIXME: cagney/2002-11-02: There has to be a better way of
|
||||
doing this. Instead of constantly saving/restoring the
|
||||
frame. Why not create a get_selected_frame() function
|
||||
that, having saved the selected frame's ID can
|
||||
automatically re-find the previously selected frame
|
||||
automatically. */
|
||||
{
|
||||
struct frame_info *fi = frame_find_by_id (old_frame);
|
||||
if (fi != NULL)
|
||||
select_frame (fi);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
error ("Left operand of assignment is not an lvalue.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user