2003-06-14 Andrew Cagney <cagney@redhat.com>
Mark Kettenis <kettenis@gnu.org> * gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter. (REGISTER_TO_VALUE, VALUE_TO_REGISTER): Replace raw buffer parameter with "frame". * gdbarch.h, gdbarch.c: Re-generate. * frame.h (put_frame_register): Declare. * frame.c (put_frame_register): New function. * arch-utils.c (legacy_convert_register_p): Add "type" parameter. (legacy_register_to_value): Rewrite, use "frame" to get the register value. (legacy_value_to_register): Rewrite, use "frame" to find the register's location before storing. * arch-utils.h (legacy_convert_register_p): Update. (legacy_register_to_value, legacy_value_to_register): Update. * findvar.c (value_from_register): Rewrite, eliminate use of REGISTER_CONVERT_TO_TYPE, pass "type" to CONVERT_REGISTER_P, pass "frame" to REGISTER_TO_VALUE. * valops.c (value_assign): Move the CONVERT_REGISTER code to the lval_reg_frame_relative + lval_register branch of the switch. Do not use REGISTER_CONVERT_FROM_TYPE. Use put_frame_register. * i386-tdep.c (I386_EBX_REGNUM, I386_ECX_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM): New defines. (i386_next_regnum, i386_convert_register_p, i386_register_to_value, i386_value_to_register): New functions. (i386_register_convertible, i386_register_convert_to_virtual, i386_convert_to_raw): Remove functions. (i386_gdbarch_init): Set convert_register_p, register_to_value and value_to_register instead of register_convertible, register_convert_to_virtual and register_convert_to_raw. * mips-tdep.c (mips_convert_register_p): New function. (mips_value_to_register): Replace mips_register_convert_from_type. (mips_register_to_value): Replace mips_register_convert_to_type. (mips_gdbarch_init): Set conver_register_p, value_to_register and register_to_value. * alpha-tdep.c (alpha_convert_register_p): Update. (alpha_value_to_register): Update, store the register. (alpha_register_to_value): Update, fetch the register.
This commit is contained in:
parent
81a58f5b70
commit
ff2e87acc7
@ -1,3 +1,43 @@
|
||||
2003-06-14 Andrew Cagney <cagney@redhat.com>
|
||||
Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
|
||||
(REGISTER_TO_VALUE, VALUE_TO_REGISTER): Replace raw buffer
|
||||
parameter with "frame".
|
||||
* gdbarch.h, gdbarch.c: Re-generate.
|
||||
* frame.h (put_frame_register): Declare.
|
||||
* frame.c (put_frame_register): New function.
|
||||
* arch-utils.c (legacy_convert_register_p): Add "type" parameter.
|
||||
(legacy_register_to_value): Rewrite, use "frame" to get the
|
||||
register value.
|
||||
(legacy_value_to_register): Rewrite, use "frame" to find the
|
||||
register's location before storing.
|
||||
* arch-utils.h (legacy_convert_register_p): Update.
|
||||
(legacy_register_to_value, legacy_value_to_register): Update.
|
||||
* findvar.c (value_from_register): Rewrite, eliminate use of
|
||||
REGISTER_CONVERT_TO_TYPE, pass "type" to CONVERT_REGISTER_P, pass
|
||||
"frame" to REGISTER_TO_VALUE.
|
||||
* valops.c (value_assign): Move the CONVERT_REGISTER code to the
|
||||
lval_reg_frame_relative + lval_register branch of the switch. Do
|
||||
not use REGISTER_CONVERT_FROM_TYPE. Use put_frame_register.
|
||||
* i386-tdep.c (I386_EBX_REGNUM, I386_ECX_REGNUM, I386_ESI_REGNUM,
|
||||
I386_EDI_REGNUM): New defines.
|
||||
(i386_next_regnum, i386_convert_register_p,
|
||||
i386_register_to_value, i386_value_to_register): New functions.
|
||||
(i386_register_convertible, i386_register_convert_to_virtual,
|
||||
i386_convert_to_raw): Remove functions.
|
||||
(i386_gdbarch_init): Set convert_register_p, register_to_value and
|
||||
value_to_register instead of register_convertible,
|
||||
register_convert_to_virtual and register_convert_to_raw.
|
||||
* mips-tdep.c (mips_convert_register_p): New function.
|
||||
(mips_value_to_register): Replace mips_register_convert_from_type.
|
||||
(mips_register_to_value): Replace mips_register_convert_to_type.
|
||||
(mips_gdbarch_init): Set conver_register_p, value_to_register and
|
||||
register_to_value.
|
||||
* alpha-tdep.c (alpha_convert_register_p): Update.
|
||||
(alpha_value_to_register): Update, store the register.
|
||||
(alpha_register_to_value): Update, fetch the register.
|
||||
|
||||
2003-06-14 Theodore A. Roth <troth@openavr.org>
|
||||
|
||||
* avr-tdep.c (avr_remote_translate_xfer_address): Delete function.
|
||||
|
@ -206,14 +206,17 @@ alpha_sts (void *out, const void *in)
|
||||
registers is different. */
|
||||
|
||||
static int
|
||||
alpha_convert_register_p (int regno)
|
||||
alpha_convert_register_p (int regno, struct type *type)
|
||||
{
|
||||
return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31);
|
||||
}
|
||||
|
||||
static void
|
||||
alpha_register_to_value (int regnum, struct type *valtype, char *in, char *out)
|
||||
alpha_register_to_value (struct frame_info *frame, int regnum,
|
||||
struct type *valtype, void *out)
|
||||
{
|
||||
char in[MAX_REGISTER_SIZE];
|
||||
frame_register_read (frame, regnum, in);
|
||||
switch (TYPE_LENGTH (valtype))
|
||||
{
|
||||
case 4:
|
||||
@ -228,8 +231,10 @@ alpha_register_to_value (int regnum, struct type *valtype, char *in, char *out)
|
||||
}
|
||||
|
||||
static void
|
||||
alpha_value_to_register (struct type *valtype, int regnum, char *in, char *out)
|
||||
alpha_value_to_register (struct frame_info *frame, int regnum,
|
||||
struct type *valtype, const void *in)
|
||||
{
|
||||
char out[MAX_REGISTER_SIZE];
|
||||
switch (TYPE_LENGTH (valtype))
|
||||
{
|
||||
case 4:
|
||||
@ -241,6 +246,7 @@ alpha_value_to_register (struct type *valtype, int regnum, char *in, char *out)
|
||||
default:
|
||||
error ("Cannot store value in floating point register");
|
||||
}
|
||||
put_frame_register (frame, regnum, out);
|
||||
}
|
||||
|
||||
|
||||
|
@ -440,23 +440,29 @@ legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
|
||||
}
|
||||
|
||||
int
|
||||
legacy_convert_register_p (int regnum)
|
||||
legacy_convert_register_p (int regnum, struct type *type)
|
||||
{
|
||||
return DEPRECATED_REGISTER_CONVERTIBLE (regnum);
|
||||
}
|
||||
|
||||
void
|
||||
legacy_register_to_value (int regnum, struct type *type,
|
||||
char *from, char *to)
|
||||
legacy_register_to_value (struct frame_info *frame, int regnum,
|
||||
struct type *type, void *to)
|
||||
{
|
||||
char from[MAX_REGISTER_SIZE];
|
||||
frame_read_register (frame, regnum, from);
|
||||
DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
|
||||
}
|
||||
|
||||
void
|
||||
legacy_value_to_register (struct type *type, int regnum,
|
||||
char *from, char *to)
|
||||
legacy_value_to_register (struct frame_info *frame, int regnum,
|
||||
struct type *type, const void *tmp)
|
||||
{
|
||||
char to[MAX_REGISTER_SIZE];
|
||||
char *from = alloca (TYPE_LENGTH (type));
|
||||
memcpy (from, from, TYPE_LENGTH (type));
|
||||
DEPRECATED_REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
|
||||
put_frame_register (frame, regnum, to);
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,9 +160,11 @@ extern int legacy_pc_in_sigtramp (CORE_ADDR pc, char *name);
|
||||
(something that is discouraged); and to convert a register to the
|
||||
type of a corresponding variable. These legacy functions preserve
|
||||
that overloaded behavour in existing targets. */
|
||||
extern int legacy_convert_register_p (int regnum);
|
||||
extern void legacy_register_to_value (int regnum, struct type *type, char *from, char *to);
|
||||
extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to);
|
||||
extern int legacy_convert_register_p (int regnum, struct type *type);
|
||||
extern void legacy_register_to_value (struct frame_info *frame, int regnum,
|
||||
struct type *type, void *to);
|
||||
extern void legacy_value_to_register (struct frame_info *frame, int regnum,
|
||||
struct type *type, const void *from);
|
||||
|
||||
/* For compatibility with older architectures, returns
|
||||
(LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid
|
||||
|
248
gdb/findvar.c
248
gdb/findvar.c
@ -624,145 +624,75 @@ addresses have not been bound by the dynamic loader. Try again when executable i
|
||||
struct value *
|
||||
value_from_register (struct type *type, int regnum, struct frame_info *frame)
|
||||
{
|
||||
char raw_buffer[MAX_REGISTER_SIZE];
|
||||
CORE_ADDR addr;
|
||||
int optim;
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
struct value *v = allocate_value (type);
|
||||
char *value_bytes = 0;
|
||||
int value_bytes_copied = 0;
|
||||
int num_storage_locs;
|
||||
enum lval_type lval;
|
||||
int len;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
len = TYPE_LENGTH (type);
|
||||
|
||||
VALUE_REGNO (v) = regnum;
|
||||
|
||||
num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
|
||||
((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
|
||||
1);
|
||||
|
||||
if (num_storage_locs > 1
|
||||
#if 0
|
||||
// OBSOLETE #ifdef GDB_TARGET_IS_H8500
|
||||
// OBSOLETE || TYPE_CODE (type) == TYPE_CODE_PTR
|
||||
// OBSOLETE #endif
|
||||
#endif
|
||||
)
|
||||
if (CONVERT_REGISTER_P (regnum, type))
|
||||
{
|
||||
/* The ISA/ABI need to something weird when obtaining the
|
||||
specified value from this register. It might need to
|
||||
re-order non-adjacent, starting with REGNUM (see MIPS and
|
||||
i386). It might need to convert the [float] register into
|
||||
the corresponding [integer] type (see Alpha). The assumption
|
||||
is that REGISTER_TO_VALUE populates the entire value
|
||||
including the location. */
|
||||
REGISTER_TO_VALUE (frame, regnum, type, VALUE_CONTENTS_RAW (v));
|
||||
VALUE_LVAL (v) = lval_reg_frame_relative;
|
||||
VALUE_FRAME_ID (v) = get_frame_id (frame);
|
||||
VALUE_FRAME_REGNUM (v) = regnum;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Value spread across multiple storage locations. */
|
||||
|
||||
int local_regnum;
|
||||
int mem_stor = 0, reg_stor = 0;
|
||||
int mem_tracking = 1;
|
||||
CORE_ADDR last_addr = 0;
|
||||
CORE_ADDR first_addr = 0;
|
||||
|
||||
value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
|
||||
int first_realnum = regnum;
|
||||
int len = TYPE_LENGTH (type);
|
||||
int value_bytes_copied;
|
||||
int optimized = 0;
|
||||
char *value_bytes = (char *) alloca (len + MAX_REGISTER_SIZE);
|
||||
|
||||
/* Copy all of the data out, whereever it may be. */
|
||||
|
||||
#if 0
|
||||
// OBSOLETE #ifdef GDB_TARGET_IS_H8500
|
||||
// OBSOLETE /* This piece of hideosity is required because the H8500 treats registers
|
||||
// OBSOLETE differently depending upon whether they are used as pointers or not. As a
|
||||
// OBSOLETE pointer, a register needs to have a page register tacked onto the front.
|
||||
// OBSOLETE An alternate way to do this would be to have gcc output different register
|
||||
// OBSOLETE numbers for the pointer & non-pointer form of the register. But, it
|
||||
// OBSOLETE doesn't, so we're stuck with this. */
|
||||
// OBSOLETE
|
||||
// OBSOLETE if (TYPE_CODE (type) == TYPE_CODE_PTR
|
||||
// OBSOLETE && len > 2)
|
||||
// OBSOLETE {
|
||||
// OBSOLETE int page_regnum;
|
||||
// OBSOLETE
|
||||
// OBSOLETE switch (regnum)
|
||||
// OBSOLETE {
|
||||
// OBSOLETE case R0_REGNUM:
|
||||
// OBSOLETE case R1_REGNUM:
|
||||
// OBSOLETE case R2_REGNUM:
|
||||
// OBSOLETE case R3_REGNUM:
|
||||
// OBSOLETE page_regnum = SEG_D_REGNUM;
|
||||
// OBSOLETE break;
|
||||
// OBSOLETE case R4_REGNUM:
|
||||
// OBSOLETE case R5_REGNUM:
|
||||
// OBSOLETE page_regnum = SEG_E_REGNUM;
|
||||
// OBSOLETE break;
|
||||
// OBSOLETE case R6_REGNUM:
|
||||
// OBSOLETE case R7_REGNUM:
|
||||
// OBSOLETE page_regnum = SEG_T_REGNUM;
|
||||
// OBSOLETE break;
|
||||
// OBSOLETE }
|
||||
// OBSOLETE
|
||||
// OBSOLETE value_bytes[0] = 0;
|
||||
// OBSOLETE get_saved_register (value_bytes + 1,
|
||||
// OBSOLETE &optim,
|
||||
// OBSOLETE &addr,
|
||||
// OBSOLETE frame,
|
||||
// OBSOLETE page_regnum,
|
||||
// OBSOLETE &lval);
|
||||
// OBSOLETE
|
||||
// OBSOLETE if (register_cached (page_regnum) == -1)
|
||||
// OBSOLETE return NULL; /* register value not available */
|
||||
// OBSOLETE
|
||||
// OBSOLETE if (lval == lval_register)
|
||||
// OBSOLETE reg_stor++;
|
||||
// OBSOLETE else
|
||||
// OBSOLETE mem_stor++;
|
||||
// OBSOLETE first_addr = addr;
|
||||
// OBSOLETE last_addr = addr;
|
||||
// OBSOLETE
|
||||
// OBSOLETE get_saved_register (value_bytes + 2,
|
||||
// OBSOLETE &optim,
|
||||
// OBSOLETE &addr,
|
||||
// OBSOLETE frame,
|
||||
// OBSOLETE regnum,
|
||||
// OBSOLETE &lval);
|
||||
// OBSOLETE
|
||||
// OBSOLETE if (register_cached (regnum) == -1)
|
||||
// OBSOLETE return NULL; /* register value not available */
|
||||
// OBSOLETE
|
||||
// OBSOLETE if (lval == lval_register)
|
||||
// OBSOLETE reg_stor++;
|
||||
// OBSOLETE else
|
||||
// OBSOLETE {
|
||||
// OBSOLETE mem_stor++;
|
||||
// OBSOLETE mem_tracking = mem_tracking && (addr == last_addr);
|
||||
// OBSOLETE }
|
||||
// OBSOLETE last_addr = addr;
|
||||
// OBSOLETE }
|
||||
// OBSOLETE else
|
||||
// OBSOLETE #endif /* GDB_TARGET_IS_H8500 */
|
||||
#endif
|
||||
for (local_regnum = regnum;
|
||||
value_bytes_copied < len;
|
||||
(value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
|
||||
++local_regnum))
|
||||
{
|
||||
int realnum;
|
||||
frame_register (frame, local_regnum, &optim, &lval, &addr,
|
||||
&realnum, value_bytes + value_bytes_copied);
|
||||
|
||||
if (register_cached (local_regnum) == -1)
|
||||
return NULL; /* register value not available */
|
||||
|
||||
if (regnum == local_regnum)
|
||||
for (local_regnum = regnum, value_bytes_copied = 0;
|
||||
value_bytes_copied < len;
|
||||
(value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
|
||||
++local_regnum))
|
||||
{
|
||||
int realnum;
|
||||
int optim;
|
||||
enum lval_type lval;
|
||||
CORE_ADDR addr;
|
||||
frame_register (frame, local_regnum, &optim, &lval, &addr,
|
||||
&realnum, value_bytes + value_bytes_copied);
|
||||
optimized += optim;
|
||||
if (register_cached (local_regnum) == -1)
|
||||
return NULL; /* register value not available */
|
||||
|
||||
if (regnum == local_regnum)
|
||||
{
|
||||
first_addr = addr;
|
||||
if (lval == lval_register)
|
||||
reg_stor++;
|
||||
else
|
||||
{
|
||||
mem_stor++;
|
||||
|
||||
mem_tracking =
|
||||
(mem_tracking
|
||||
&& (regnum == local_regnum
|
||||
|| addr == last_addr));
|
||||
}
|
||||
last_addr = addr;
|
||||
}
|
||||
|
||||
first_realnum = realnum;
|
||||
}
|
||||
if (lval == lval_register)
|
||||
reg_stor++;
|
||||
else
|
||||
{
|
||||
mem_stor++;
|
||||
|
||||
mem_tracking = (mem_tracking
|
||||
&& (regnum == local_regnum
|
||||
|| addr == last_addr));
|
||||
}
|
||||
last_addr = addr;
|
||||
}
|
||||
|
||||
/* FIXME: cagney/2003-06-04: Shouldn't this always use
|
||||
lval_reg_frame_relative? If it doesn't and the register's
|
||||
location changes (say after a resume) then this value is
|
||||
going to have wrong information. */
|
||||
if ((reg_stor && mem_stor)
|
||||
|| (mem_stor && !mem_tracking))
|
||||
/* Mixed storage; all of the hassle we just went through was
|
||||
@ -781,67 +711,29 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
|
||||
{
|
||||
VALUE_LVAL (v) = lval_register;
|
||||
VALUE_ADDRESS (v) = first_addr;
|
||||
VALUE_REGNO (v) = first_realnum;
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"value_from_register: Value not stored anywhere!");
|
||||
|
||||
VALUE_OPTIMIZED_OUT (v) = optim;
|
||||
|
||||
|
||||
VALUE_OPTIMIZED_OUT (v) = optimized;
|
||||
|
||||
/* Any structure stored in more than one register will always be
|
||||
an integral number of registers. Otherwise, you'd need to do
|
||||
an integral number of registers. Otherwise, you need to do
|
||||
some fiddling with the last register copied here for little
|
||||
endian machines. */
|
||||
|
||||
/* Copy into the contents section of the value. */
|
||||
memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len);
|
||||
|
||||
/* Finally do any conversion necessary when extracting this
|
||||
type from more than one register. */
|
||||
#ifdef REGISTER_CONVERT_TO_TYPE
|
||||
REGISTER_CONVERT_TO_TYPE (regnum, type, VALUE_CONTENTS_RAW (v));
|
||||
#endif
|
||||
return v;
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
|
||||
&& len < REGISTER_RAW_SIZE (regnum))
|
||||
/* Big-endian, and we want less than full size. */
|
||||
VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
|
||||
else
|
||||
VALUE_OFFSET (v) = 0;
|
||||
memcpy (VALUE_CONTENTS_RAW (v), value_bytes + VALUE_OFFSET (v), len);
|
||||
}
|
||||
|
||||
/* Data is completely contained within a single register. Locate the
|
||||
register's contents in a real register or in core;
|
||||
read the data in raw format. */
|
||||
|
||||
{
|
||||
int realnum;
|
||||
frame_register (frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer);
|
||||
}
|
||||
|
||||
if (register_cached (regnum) == -1)
|
||||
return NULL; /* register value not available */
|
||||
|
||||
VALUE_OPTIMIZED_OUT (v) = optim;
|
||||
VALUE_LVAL (v) = lval;
|
||||
VALUE_ADDRESS (v) = addr;
|
||||
|
||||
/* Convert the raw register to the corresponding data value's memory
|
||||
format, if necessary. */
|
||||
|
||||
if (CONVERT_REGISTER_P (regnum))
|
||||
{
|
||||
REGISTER_TO_VALUE (regnum, type, raw_buffer, VALUE_CONTENTS_RAW (v));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Raw and virtual formats are the same for this register. */
|
||||
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG && len < REGISTER_RAW_SIZE (regnum))
|
||||
{
|
||||
/* Big-endian, and we want less than full size. */
|
||||
VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
|
||||
}
|
||||
|
||||
memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/* Given a struct symbol for a variable or function,
|
||||
and a stack frame id,
|
||||
|
30
gdb/frame.c
30
gdb/frame.c
@ -673,6 +673,36 @@ frame_read_signed_register (struct frame_info *frame, int regnum,
|
||||
frame_unwind_signed_register (frame->next, regnum, val);
|
||||
}
|
||||
|
||||
void
|
||||
put_frame_register (struct frame_info *frame, int regnum, const void *buf)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
int realnum;
|
||||
int optim;
|
||||
enum lval_type lval;
|
||||
CORE_ADDR addr;
|
||||
frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
|
||||
if (optim)
|
||||
error ("Attempt to assign to a value that was optimized out.");
|
||||
switch (lval)
|
||||
{
|
||||
case lval_memory:
|
||||
{
|
||||
/* FIXME: write_memory doesn't yet take constant buffers.
|
||||
Arrrg! */
|
||||
char tmp[MAX_REGISTER_SIZE];
|
||||
memcpy (tmp, buf, register_size (gdbarch, regnum));
|
||||
write_memory (addr, tmp, register_size (gdbarch, regnum));
|
||||
break;
|
||||
}
|
||||
case lval_register:
|
||||
regcache_cooked_write (current_regcache, realnum, buf);
|
||||
break;
|
||||
default:
|
||||
error ("Attempt to assign to an unmodifiable value.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
deprecated_unwind_get_saved_register (char *raw_buffer,
|
||||
int *optimizedp,
|
||||
|
@ -332,6 +332,12 @@ extern void frame_read_signed_register (struct frame_info *frame,
|
||||
extern void frame_read_unsigned_register (struct frame_info *frame,
|
||||
int regnum, ULONGEST *val);
|
||||
|
||||
/* The reverse. Store a register value relative to the specified
|
||||
frame. Note: this call makes the frame's state undefined. The
|
||||
register and frame caches must be flushed. */
|
||||
extern void put_frame_register (struct frame_info *frame, int regnum,
|
||||
const void *buf);
|
||||
|
||||
/* Map between a frame register number and its name. A frame register
|
||||
space is a superset of the cooked register space --- it also
|
||||
includes builtin registers. If NAMELEN is negative, use the NAME's
|
||||
|
@ -989,8 +989,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
#ifdef CONVERT_REGISTER_P
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: %s # %s\n",
|
||||
"CONVERT_REGISTER_P(regnum)",
|
||||
XSTRING (CONVERT_REGISTER_P (regnum)));
|
||||
"CONVERT_REGISTER_P(regnum, type)",
|
||||
XSTRING (CONVERT_REGISTER_P (regnum, type)));
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: CONVERT_REGISTER_P = <0x%08lx>\n",
|
||||
@ -2148,8 +2148,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
/* Macro might contain `[{}]' when not multi-arch */
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: %s # %s\n",
|
||||
"REGISTER_TO_VALUE(regnum, type, from, to)",
|
||||
XSTRING (REGISTER_TO_VALUE (regnum, type, from, to)));
|
||||
"REGISTER_TO_VALUE(frame, regnum, type, buf)",
|
||||
XSTRING (REGISTER_TO_VALUE (frame, regnum, type, buf)));
|
||||
#endif
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
@ -2670,8 +2670,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
||||
/* Macro might contain `[{}]' when not multi-arch */
|
||||
fprintf_unfiltered (file,
|
||||
"gdbarch_dump: %s # %s\n",
|
||||
"VALUE_TO_REGISTER(type, regnum, from, to)",
|
||||
XSTRING (VALUE_TO_REGISTER (type, regnum, from, to)));
|
||||
"VALUE_TO_REGISTER(frame, regnum, type, buf)",
|
||||
XSTRING (VALUE_TO_REGISTER (frame, regnum, type, buf)));
|
||||
#endif
|
||||
if (GDB_MULTI_ARCH)
|
||||
fprintf_unfiltered (file,
|
||||
@ -4335,7 +4335,7 @@ set_gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
int
|
||||
gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum)
|
||||
gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
if (gdbarch->convert_register_p == 0)
|
||||
@ -4343,7 +4343,7 @@ gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum)
|
||||
"gdbarch: gdbarch_convert_register_p invalid");
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_register_p called\n");
|
||||
return gdbarch->convert_register_p (regnum);
|
||||
return gdbarch->convert_register_p (regnum, type);
|
||||
}
|
||||
|
||||
void
|
||||
@ -4354,7 +4354,7 @@ set_gdbarch_convert_register_p (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
void
|
||||
gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to)
|
||||
gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
if (gdbarch->register_to_value == 0)
|
||||
@ -4362,7 +4362,7 @@ gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *typ
|
||||
"gdbarch: gdbarch_register_to_value invalid");
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n");
|
||||
gdbarch->register_to_value (regnum, type, from, to);
|
||||
gdbarch->register_to_value (frame, regnum, type, buf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -4373,7 +4373,7 @@ set_gdbarch_register_to_value (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
void
|
||||
gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to)
|
||||
gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const void *buf)
|
||||
{
|
||||
gdb_assert (gdbarch != NULL);
|
||||
if (gdbarch->value_to_register == 0)
|
||||
@ -4381,7 +4381,7 @@ gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnu
|
||||
"gdbarch: gdbarch_value_to_register invalid");
|
||||
if (gdbarch_debug >= 2)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_value_to_register called\n");
|
||||
gdbarch->value_to_register (type, regnum, from, to);
|
||||
gdbarch->value_to_register (frame, regnum, type, buf);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1688,47 +1688,47 @@ extern void set_gdbarch_deprecated_register_convert_to_raw (struct gdbarch *gdba
|
||||
|
||||
/* Default (function) for non- multi-arch platforms. */
|
||||
#if (!GDB_MULTI_ARCH) && !defined (CONVERT_REGISTER_P)
|
||||
#define CONVERT_REGISTER_P(regnum) (legacy_convert_register_p (regnum))
|
||||
#define CONVERT_REGISTER_P(regnum, type) (legacy_convert_register_p (regnum, type))
|
||||
#endif
|
||||
|
||||
typedef int (gdbarch_convert_register_p_ftype) (int regnum);
|
||||
extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum);
|
||||
typedef int (gdbarch_convert_register_p_ftype) (int regnum, struct type *type);
|
||||
extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type);
|
||||
extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p);
|
||||
#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (CONVERT_REGISTER_P)
|
||||
#error "Non multi-arch definition of CONVERT_REGISTER_P"
|
||||
#endif
|
||||
#if !defined (CONVERT_REGISTER_P)
|
||||
#define CONVERT_REGISTER_P(regnum) (gdbarch_convert_register_p (current_gdbarch, regnum))
|
||||
#define CONVERT_REGISTER_P(regnum, type) (gdbarch_convert_register_p (current_gdbarch, regnum, type))
|
||||
#endif
|
||||
|
||||
/* Default (function) for non- multi-arch platforms. */
|
||||
#if (!GDB_MULTI_ARCH) && !defined (REGISTER_TO_VALUE)
|
||||
#define REGISTER_TO_VALUE(regnum, type, from, to) (legacy_register_to_value (regnum, type, from, to))
|
||||
#define REGISTER_TO_VALUE(frame, regnum, type, buf) (legacy_register_to_value (frame, regnum, type, buf))
|
||||
#endif
|
||||
|
||||
typedef void (gdbarch_register_to_value_ftype) (int regnum, struct type *type, char *from, char *to);
|
||||
extern void gdbarch_register_to_value (struct gdbarch *gdbarch, int regnum, struct type *type, char *from, char *to);
|
||||
typedef void (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, void *buf);
|
||||
extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, void *buf);
|
||||
extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value);
|
||||
#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (REGISTER_TO_VALUE)
|
||||
#error "Non multi-arch definition of REGISTER_TO_VALUE"
|
||||
#endif
|
||||
#if !defined (REGISTER_TO_VALUE)
|
||||
#define REGISTER_TO_VALUE(regnum, type, from, to) (gdbarch_register_to_value (current_gdbarch, regnum, type, from, to))
|
||||
#define REGISTER_TO_VALUE(frame, regnum, type, buf) (gdbarch_register_to_value (current_gdbarch, frame, regnum, type, buf))
|
||||
#endif
|
||||
|
||||
/* Default (function) for non- multi-arch platforms. */
|
||||
#if (!GDB_MULTI_ARCH) && !defined (VALUE_TO_REGISTER)
|
||||
#define VALUE_TO_REGISTER(type, regnum, from, to) (legacy_value_to_register (type, regnum, from, to))
|
||||
#define VALUE_TO_REGISTER(frame, regnum, type, buf) (legacy_value_to_register (frame, regnum, type, buf))
|
||||
#endif
|
||||
|
||||
typedef void (gdbarch_value_to_register_ftype) (struct type *type, int regnum, char *from, char *to);
|
||||
extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct type *type, int regnum, char *from, char *to);
|
||||
typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, int regnum, struct type *type, const void *buf);
|
||||
extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const void *buf);
|
||||
extern void set_gdbarch_value_to_register (struct gdbarch *gdbarch, gdbarch_value_to_register_ftype *value_to_register);
|
||||
#if (GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL) && defined (VALUE_TO_REGISTER)
|
||||
#error "Non multi-arch definition of VALUE_TO_REGISTER"
|
||||
#endif
|
||||
#if !defined (VALUE_TO_REGISTER)
|
||||
#define VALUE_TO_REGISTER(type, regnum, from, to) (gdbarch_value_to_register (current_gdbarch, type, regnum, from, to))
|
||||
#define VALUE_TO_REGISTER(frame, regnum, type, buf) (gdbarch_value_to_register (current_gdbarch, frame, regnum, type, buf))
|
||||
#endif
|
||||
|
||||
/* Default (function) for non- multi-arch platforms. */
|
||||
|
@ -585,9 +585,9 @@ f:2:DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL:void:deprecated_register_convert_to_v
|
||||
# For raw <-> cooked register conversions, replaced by pseudo registers.
|
||||
f:2:DEPRECATED_REGISTER_CONVERT_TO_RAW:void:deprecated_register_convert_to_raw:struct type *type, int regnum, const char *from, char *to:type, regnum, from, to:::0::0
|
||||
#
|
||||
f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum:regnum::0:legacy_convert_register_p::0
|
||||
f:1:REGISTER_TO_VALUE:void:register_to_value:int regnum, struct type *type, char *from, char *to:regnum, type, from, to::0:legacy_register_to_value::0
|
||||
f:1:VALUE_TO_REGISTER:void:value_to_register:struct type *type, int regnum, char *from, char *to:type, regnum, from, to::0:legacy_value_to_register::0
|
||||
f:1:CONVERT_REGISTER_P:int:convert_register_p:int regnum, struct type *type:regnum, type::0:legacy_convert_register_p::0
|
||||
f:1:REGISTER_TO_VALUE:void:register_to_value:struct frame_info *frame, int regnum, struct type *type, void *buf:frame, regnum, type, buf::0:legacy_register_to_value::0
|
||||
f:1:VALUE_TO_REGISTER:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const void *buf:frame, regnum, type, buf::0:legacy_value_to_register::0
|
||||
#
|
||||
f:2:POINTER_TO_ADDRESS:CORE_ADDR:pointer_to_address:struct type *type, const void *buf:type, buf:::unsigned_pointer_to_address::0
|
||||
f:2:ADDRESS_TO_POINTER:void:address_to_pointer:struct type *type, void *buf, CORE_ADDR addr:type, buf, addr:::unsigned_address_to_pointer::0
|
||||
|
165
gdb/i386-tdep.c
165
gdb/i386-tdep.c
@ -1324,65 +1324,148 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
else
|
||||
regcache_raw_write (regcache, regnum, buf);
|
||||
}
|
||||
|
||||
|
||||
/* Return true iff register REGNUM's virtual format is different from
|
||||
its raw format. Note that this definition assumes that the host
|
||||
supports IEEE 32-bit floats, since it doesn't say that SSE
|
||||
registers need conversion. Even if we can't find a counterexample,
|
||||
this is still sloppy. */
|
||||
/* These registers don't have pervasive standard uses. Move them to
|
||||
i386-tdep.h if necessary. */
|
||||
|
||||
#define I386_EBX_REGNUM 3 /* %ebx */
|
||||
#define I386_ECX_REGNUM 1 /* %ecx */
|
||||
#define I386_ESI_REGNUM 6 /* %esi */
|
||||
#define I386_EDI_REGNUM 7 /* %edi */
|
||||
|
||||
/* Return the register number of the register allocated by GCC after
|
||||
REGNUM, or -1 if there is no such register. */
|
||||
|
||||
static int
|
||||
i386_register_convertible (int regnum)
|
||||
i386_next_regnum (int regnum)
|
||||
{
|
||||
/* GCC allocates the registers in the order:
|
||||
|
||||
%eax, %edx, %ecx, %ebx, %esi, %edi, %ebp, %esp, ...
|
||||
|
||||
Since storing a variable in %esp doesn't make any sense we return
|
||||
-1 for %ebp and for %esp itself. */
|
||||
static int next_regnum[] =
|
||||
{
|
||||
I386_EDX_REGNUM, /* Slot for %eax. */
|
||||
I386_EBX_REGNUM, /* Slot for %ecx. */
|
||||
I386_ECX_REGNUM, /* Slot for %edx. */
|
||||
I386_ESI_REGNUM, /* Slot for %ebx. */
|
||||
-1, -1, /* Slots for %esp and %ebp. */
|
||||
I386_EDI_REGNUM, /* Slot for %esi. */
|
||||
I386_EBP_REGNUM /* Slot for %edi. */
|
||||
};
|
||||
|
||||
if (regnum < sizeof (next_regnum) / sizeof (next_regnum[0]))
|
||||
return next_regnum[regnum];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return nonzero if a value of type TYPE stored in register REGNUM
|
||||
needs any special handling. */
|
||||
|
||||
static int
|
||||
i386_convert_register_p (int regnum, struct type *type)
|
||||
{
|
||||
/* Values may be spread across multiple registers. Most debugging
|
||||
formats aren't expressive enough to specify the locations, so
|
||||
some heuristics is involved. Right now we only handle types that
|
||||
are exactly 8 bytes long as GCC doesn't seem to put any other
|
||||
types into registers. */
|
||||
if (TYPE_LENGTH (type) == 8 && i386_next_regnum (regnum) != -1)
|
||||
return 1;
|
||||
|
||||
return i386_fp_regnum_p (regnum);
|
||||
}
|
||||
|
||||
/* Convert data from raw format for register REGNUM in buffer FROM to
|
||||
virtual format with type TYPE in buffer TO. */
|
||||
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
|
||||
return its contents in TO. */
|
||||
|
||||
static void
|
||||
i386_register_convert_to_virtual (int regnum, struct type *type,
|
||||
char *from, char *to)
|
||||
i386_register_to_value (struct frame_info *frame, int regnum,
|
||||
struct type *type, void *to)
|
||||
{
|
||||
gdb_assert (i386_fp_regnum_p (regnum));
|
||||
/* FIXME: kettenis/20030609: What should we do if REGNUM isn't
|
||||
available in FRAME (i.e. if it wasn't saved)? */
|
||||
|
||||
/* We only support floating-point values. */
|
||||
if (TYPE_CODE (type) != TYPE_CODE_FLT)
|
||||
if (i386_fp_regnum_p (regnum))
|
||||
{
|
||||
warning ("Cannot convert floating-point register value "
|
||||
"to non-floating-point type.");
|
||||
memset (to, 0, TYPE_LENGTH (type));
|
||||
return;
|
||||
}
|
||||
char from[I386_MAX_REGISTER_SIZE];
|
||||
|
||||
/* Convert to TYPE. This should be a no-op if TYPE is equivalent to
|
||||
the extended floating-point format used by the FPU. */
|
||||
convert_typed_floating (from, builtin_type_i387_ext, to, type);
|
||||
/* We only support floating-point values. */
|
||||
if (TYPE_CODE (type) != TYPE_CODE_FLT)
|
||||
{
|
||||
warning ("Cannot convert floating-point register value "
|
||||
"to non-floating-point type.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert to TYPE. This should be a no-op if TYPE is
|
||||
equivalent to the extended floating-point format used by the
|
||||
FPU. */
|
||||
frame_read_register (frame, regnum, from);
|
||||
convert_typed_floating (from, builtin_type_i387_ext, to, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdb_assert (TYPE_LENGTH (type) == 8);
|
||||
|
||||
/* Read the first part. */
|
||||
gdb_assert (register_size (current_gdbarch, regnum) == 4);
|
||||
frame_read_register (frame, regnum, (char *) to + 0);
|
||||
|
||||
/* Read the second part. */
|
||||
regnum = i386_next_regnum (regnum);
|
||||
gdb_assert (regnum != -1);
|
||||
gdb_assert (register_size (current_gdbarch, regnum));
|
||||
frame_read_register (frame, regnum, (char *) to + 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert data from virtual format with type TYPE in buffer FROM to
|
||||
raw format for register REGNUM in buffer TO. */
|
||||
/* Write the contents FROM of a value of type TYPE into register
|
||||
REGNUM in frame FRAME. */
|
||||
|
||||
static void
|
||||
i386_register_convert_to_raw (struct type *type, int regnum,
|
||||
const char *from, char *to)
|
||||
i386_value_to_register (struct frame_info *frame, int regnum,
|
||||
struct type *type, const void *from)
|
||||
{
|
||||
gdb_assert (i386_fp_regnum_p (regnum));
|
||||
|
||||
/* We only support floating-point values. */
|
||||
if (TYPE_CODE (type) != TYPE_CODE_FLT)
|
||||
if (i386_fp_regnum_p (regnum))
|
||||
{
|
||||
warning ("Cannot convert non-floating-point type "
|
||||
"to floating-point register value.");
|
||||
memset (to, 0, TYPE_LENGTH (type));
|
||||
return;
|
||||
}
|
||||
char to[I386_MAX_REGISTER_SIZE];
|
||||
|
||||
/* Convert from TYPE. This should be a no-op if TYPE is equivalent
|
||||
to the extended floating-point format used by the FPU. */
|
||||
convert_typed_floating (from, type, to, builtin_type_i387_ext);
|
||||
/* We only support floating-point values. */
|
||||
if (TYPE_CODE (type) != TYPE_CODE_FLT)
|
||||
{
|
||||
warning ("Cannot convert non-floating-point type "
|
||||
"to floating-point register value.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert from TYPE. This should be a no-op if TYPE is
|
||||
equivalent to the extended floating-point format used by the
|
||||
FPU. */
|
||||
convert_typed_floating (from, type, to, builtin_type_i387_ext);
|
||||
put_frame_register (frame, regnum, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdb_assert (TYPE_LENGTH (type) == 8);
|
||||
|
||||
/* Write the first part. */
|
||||
gdb_assert (register_size (current_gdbarch, regnum) == 4);
|
||||
put_frame_register (frame, regnum, (const char *) from + 0);
|
||||
|
||||
/* Write the second part. */
|
||||
regnum = i386_next_regnum (regnum);
|
||||
gdb_assert (regnum != -1);
|
||||
gdb_assert (register_size (current_gdbarch, regnum) == 4);
|
||||
put_frame_register (frame, regnum, (const char *) from + 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef STATIC_TRANSFORM_NAME
|
||||
/* SunPRO encodes the static variables. This is not related to C++
|
||||
@ -1692,9 +1775,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
/* Call dummy code. */
|
||||
set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
|
||||
|
||||
set_gdbarch_deprecated_register_convertible (gdbarch, i386_register_convertible);
|
||||
set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, i386_register_convert_to_virtual);
|
||||
set_gdbarch_deprecated_register_convert_to_raw (gdbarch, i386_register_convert_to_raw);
|
||||
set_gdbarch_convert_register_p (gdbarch, i386_convert_register_p);
|
||||
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
|
||||
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
|
||||
|
||||
set_gdbarch_extract_return_value (gdbarch, i386_extract_return_value);
|
||||
set_gdbarch_store_return_value (gdbarch, i386_store_return_value);
|
||||
|
@ -634,36 +634,30 @@ mips_register_convert_to_raw (struct type *virtual_type, int n,
|
||||
TYPE_LENGTH (virtual_type));
|
||||
}
|
||||
|
||||
void
|
||||
mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
|
||||
static int
|
||||
mips_convert_register_p (int regnum, struct type *type)
|
||||
{
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
|
||||
&& REGISTER_RAW_SIZE (regnum) == 4
|
||||
&& (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
|
||||
&& TYPE_CODE(type) == TYPE_CODE_FLT
|
||||
&& TYPE_LENGTH(type) == 8)
|
||||
{
|
||||
char temp[4];
|
||||
memcpy (temp, ((char *)(buffer))+4, 4);
|
||||
memcpy (((char *)(buffer))+4, (buffer), 4);
|
||||
memcpy (((char *)(buffer)), temp, 4);
|
||||
}
|
||||
return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
|
||||
&& REGISTER_RAW_SIZE (regnum) == 4
|
||||
&& (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
|
||||
&& TYPE_CODE(type) == TYPE_CODE_FLT
|
||||
&& TYPE_LENGTH(type) == 8);
|
||||
}
|
||||
|
||||
void
|
||||
mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
|
||||
mips_register_to_value (struct frame_info *frame, int regnum,
|
||||
struct type *type, void *to)
|
||||
{
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
|
||||
&& REGISTER_RAW_SIZE (regnum) == 4
|
||||
&& (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
|
||||
&& TYPE_CODE(type) == TYPE_CODE_FLT
|
||||
&& TYPE_LENGTH(type) == 8)
|
||||
{
|
||||
char temp[4];
|
||||
memcpy (temp, ((char *)(buffer))+4, 4);
|
||||
memcpy (((char *)(buffer))+4, (buffer), 4);
|
||||
memcpy (((char *)(buffer)), temp, 4);
|
||||
}
|
||||
frame_read_register (frame, regnum + 0, (char *) to + 4);
|
||||
frame_read_register (frame, regnum + 1, (char *) to + 0);
|
||||
}
|
||||
|
||||
void
|
||||
mips_value_to_register (struct frame_info *frame, int regnum,
|
||||
struct type *type, const void *from)
|
||||
{
|
||||
put_frame_register (frame, regnum + 0, (const char *) from + 4);
|
||||
put_frame_register (frame, regnum + 1, (const char *) from + 0);
|
||||
}
|
||||
|
||||
/* Return the GDB type object for the "standard" data type
|
||||
|
160
gdb/valops.c
160
gdb/valops.c
@ -498,22 +498,6 @@ value_assign (struct value *toval, struct value *fromval)
|
||||
COERCE_ARRAY (fromval);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
/* If TOVAL is a special machine register requiring conversion
|
||||
of program values to a special raw format,
|
||||
convert FROMVAL's contents now, with result in `raw_buffer',
|
||||
and set USE_BUFFER to the number of bytes to write. */
|
||||
|
||||
if (VALUE_REGNO (toval) >= 0)
|
||||
{
|
||||
int regno = VALUE_REGNO (toval);
|
||||
if (CONVERT_REGISTER_P (regno))
|
||||
{
|
||||
struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
|
||||
VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
|
||||
use_buffer = REGISTER_RAW_SIZE (regno);
|
||||
}
|
||||
}
|
||||
|
||||
/* Since modifying a register can trash the frame chain, and modifying memory
|
||||
can trash the frame cache, we save the old frame and then restore the new
|
||||
frame afterwards. */
|
||||
@ -587,17 +571,8 @@ value_assign (struct value *toval, struct value *fromval)
|
||||
case lval_reg_frame_relative:
|
||||
case lval_register:
|
||||
{
|
||||
/* 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_copied;
|
||||
int amount_to_copy;
|
||||
char *buffer;
|
||||
int value_reg;
|
||||
int reg_offset;
|
||||
int byte_offset;
|
||||
int regno;
|
||||
struct frame_info *frame;
|
||||
int value_reg;
|
||||
|
||||
/* Figure out which frame this is in currently. */
|
||||
if (VALUE_LVAL (toval) == lval_register)
|
||||
@ -613,92 +588,77 @@ value_assign (struct value *toval, struct value *fromval)
|
||||
|
||||
if (!frame)
|
||||
error ("Value being assigned to is no longer active.");
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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_SIZE);
|
||||
|
||||
/* Copy it in. */
|
||||
for (regno = reg_offset, amount_copied = 0;
|
||||
amount_copied < amount_to_copy;
|
||||
amount_copied += REGISTER_RAW_SIZE (regno), regno++)
|
||||
{
|
||||
frame_register_read (frame, regno, buffer + amount_copied);
|
||||
}
|
||||
|
||||
/* Modify what needs to be modified. */
|
||||
if (VALUE_BITSIZE (toval))
|
||||
if (VALUE_LVAL (toval) == lval_reg_frame_relative
|
||||
&& CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type))
|
||||
{
|
||||
modify_field (buffer + byte_offset,
|
||||
value_as_long (fromval),
|
||||
VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
|
||||
}
|
||||
else if (use_buffer)
|
||||
{
|
||||
memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
|
||||
/* If TOVAL is a special machine register requiring
|
||||
conversion of program values to a special raw format. */
|
||||
VALUE_TO_REGISTER (frame, VALUE_FRAME_REGNUM (toval),
|
||||
type, VALUE_CONTENTS (fromval));
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
}
|
||||
/* TOVAL 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_copied;
|
||||
int amount_to_copy;
|
||||
char *buffer;
|
||||
int reg_offset;
|
||||
int byte_offset;
|
||||
int regno;
|
||||
|
||||
/* Copy it out. */
|
||||
for (regno = reg_offset, amount_copied = 0;
|
||||
amount_copied < amount_to_copy;
|
||||
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. */
|
||||
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,
|
||||
REGISTER_RAW_SIZE (regno));
|
||||
else if (lval == lval_register)
|
||||
regcache_cooked_write (current_regcache, realnum,
|
||||
(buffer + amount_copied));
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Compute the number of register aligned values that need
|
||||
to be copied. */
|
||||
if (VALUE_BITSIZE (toval))
|
||||
amount_to_copy = byte_offset + 1;
|
||||
else
|
||||
error ("Attempt to assign to an unmodifiable value.");
|
||||
}
|
||||
amount_to_copy = byte_offset + TYPE_LENGTH (type);
|
||||
|
||||
/* And a bounce buffer. Be slightly over generous. */
|
||||
buffer = (char *) alloca (amount_to_copy + MAX_REGISTER_SIZE);
|
||||
|
||||
/* Copy it in. */
|
||||
for (regno = reg_offset, amount_copied = 0;
|
||||
amount_copied < amount_to_copy;
|
||||
amount_copied += REGISTER_RAW_SIZE (regno), regno++)
|
||||
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));
|
||||
else if (use_buffer)
|
||||
memcpy (buffer + VALUE_OFFSET (toval), raw_buffer, use_buffer);
|
||||
else
|
||||
memcpy (buffer + byte_offset, VALUE_CONTENTS (fromval),
|
||||
TYPE_LENGTH (type));
|
||||
|
||||
/* Copy it out. */
|
||||
for (regno = reg_offset, amount_copied = 0;
|
||||
amount_copied < amount_to_copy;
|
||||
amount_copied += REGISTER_RAW_SIZE (regno), regno++)
|
||||
put_frame_register (frame, regno, buffer + amount_copied);
|
||||
|
||||
}
|
||||
if (register_changed_hook)
|
||||
register_changed_hook (-1);
|
||||
target_changed_event ();
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
error ("Left operand of assignment is not an lvalue.");
|
||||
|
Loading…
Reference in New Issue
Block a user