* [wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE
@ 2003-06-04 19:38 Andrew Cagney
2003-06-04 21:45 ` Mark Kettenis
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Cagney @ 2003-06-04 19:38 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3156 bytes --]
Hello,
I've been looking at merging the MIPS specific REGISTER_TO_TYPE with
REGISTER_TO_VALUE but first some background.
GDB currently has three register<->type conversion methods (I'm only
looking at the forward conversions here):
REGISTER_CONVERTIBLE:
REGISTER_CONVERT_TO_RAW:
REGISTER_CONVERT_TO_VIRTUAL:
Used by value_/of/_register.
They date back to when GDB was trying to raw register values into an
internal form. For instance (from memory), the m68k was converting it's
floating point registers into strict ieee.
These methods are no longer needed, Instead, registers are always
exactly described by their type and the register's underlying contents
are left unchanged. If, as with the MIPS, a register has multiple
views, then it is handled by having multiple pseudo registers.
CONVERT_REGISTER_P
REGISTER_TO_VALUE
VALUE_TO_REGISTER
Use by value_/from/_register.
These methods are used to perform single register <-> value
conversions. For instance, the Alpha will store integer values
(variables) in floating point registers. When GDB goes to extract an
integer's value it needs to perform an Alpha specific float<->integer
conversion. The original code re-used REGISTER_CONVERTIBLE but was
later separated out.
REGISTER_TO_TYPE
TYPE_TO_REGISTER
Used by value_/from/_register.
The MIPS uses this to convert a value spread across multiple
registers (REGISTER_TO_VALUE applies to a single register only).
So ...
The REGISTER_CONVERTIBLE series is ``dead''. I should at least
deprecate them. The only thing really making them stay around is the
MIPS and there Kevins stuff should eliminate it. The other
architectures still using them can (as the Alpha just did) simply switch
to REGISTER_TO_VALUE.
As for REGISTER_TO_TYPE and REGISTER_TO_VALUE, they very much have
overlapping functionality. The only significant difference is that one
applies to a single register, while the second applies to multiple
registers. Even the condition selecting which to apply is ``magic''.
num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
1);
if (num_storage_locs > 1
... REGISTER_TO_TYPE ...
else
... REGISTER_TO_VALUE ...
(remember a register can still have different raw and virtual sizes :-()
With this in mind, I'm thinking that REGISTER_TO_TYPE and
REGISTER_TO_VALUE should be merged. To that end, I can see several ways
of doing it:
- Don't merge - add REGISTER_TO_TYPE to the architecture vector
- Retain the current logic - just apply REGISTER_TO_VALUE to values
stored across multiple registers
- Add a frame parameter to REGISTER_TO_VALUE and make it responsible for
both extracting the bytes from the register[s] and then storing them in
the ``struct value''.
The last option is interesting, it would let the target draw the value
from any register based on REGNUM. The i386 with its long-long problem
might be interested in this (you'll notice in the patch I made an
attempt at doing this only I didn't see it affect the test results).
Thoughts?
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 27644 bytes --]
2003-06-04 Andrew Cagney <cagney@redhat.com>
* mips-tdep.c (mips_value_to_register): Replace
mips_register_convert_to_raw.
* mips-tdep.c (mips_register_to_value): Replace
mips_register_convert_to_virtual.
(mips_gdbarch_init): Set conver_register_p, value_to_register and
register_to_value.
* i386-tdep.c (i386_convert_register_p): Replace
i386_register_convertible.
(i386_register_to_value): Replace
i386_register_convert_to_virtual.
(i386_value_to_register): Replace i386_register_convert_to_raw.
* arch-utils.c (legacy_convert_register_p): Update.
(legacy_register_to_value): Update. Use "frame" to get the
register value.
* arch-utils.h (legacy_convert_register_p): Add "type" parameter.
(legacy_register_to_value): Add "frame" parameter, drop "from"
parameter.
* valops.c (value_assign): Pass the value's type to
CONVERT_REGISTER_P.
* 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.
* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
(REGISTER_TO_VALUE): Add a "frame" and drop "from" parameter.
* gdbarch.h, gdbarch.c: Re-generate.
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.83
diff -u -r1.83 arch-utils.c
--- arch-utils.c 15 May 2003 22:58:36 -0000 1.83
+++ arch-utils.c 4 Jun 2003 18:34:52 -0000
@@ -440,16 +440,18 @@
}
int
-legacy_convert_register_p (int regnum)
+legacy_convert_register_p (int regnum, struct type *type)
{
return 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 *buf)
{
- REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+ char tmp[MAX_REGISTER_SIZE];
+ frame_read_register (frame, regnum, tmp);
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, type, tmp, buf);
}
void
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.46
diff -u -r1.46 arch-utils.h
--- arch-utils.h 15 May 2003 22:58:36 -0000 1.46
+++ arch-utils.h 4 Jun 2003 18:34:52 -0000
@@ -165,8 +165,8 @@
(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 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 *buf);
extern void legacy_value_to_register (struct type *type, int regnum, char *from, char *to);
/* For compatibility with older architectures, returns
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.57
diff -u -r1.57 findvar.c
--- findvar.c 2 Jun 2003 02:09:39 -0000 1.57
+++ findvar.c 4 Jun 2003 18:34:52 -0000
@@ -624,145 +624,80 @@
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 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))
+ {
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ /* The ISA/ABI need to something weird when obtaining the
+ specified value from this register. It might need to combine
+ several registers, starting with REGNUM, in a strange way
+ (see MIPS and i386). It might need to convert the [float]
+ register into the corresponding [integer] type (see Alpha). */
+ /* Probe the ABI to find out where this first register lives.
+ Don't fetch the value. Use that information to describe the
+ variable location. Then ask the ABI for the actual value. */
+ /* Is this the best way of doing this? The alternative would be
+ to make REGISTER_TO_VALUE entirely responsible for populating
+ the value. */
+ frame_register (frame, regnum, &optim, &lval, &addr, &realnum, NULL);
+ REGISTER_TO_VALUE (frame, regnum, type, VALUE_CONTENTS_RAW (v));
+ VALUE_REGNO (v) = realnum;
+ VALUE_OPTIMIZED_OUT (v) = optim;
+ VALUE_LVAL (v) = lval;
+ VALUE_ADDRESS (v) = addr;
+ }
+ 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;
+ }
+
if ((reg_stor && mem_stor)
|| (mem_stor && !mem_tracking))
/* Mixed storage; all of the hassle we just went through was
@@ -781,67 +716,29 @@
{
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;
- }
-
- /* 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);
+ 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);
}
-
return v;
}
+
\f
/* Given a struct symbol for a variable or function,
and a stack frame id,
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.218
diff -u -r1.218 gdbarch.c
--- gdbarch.c 2 Jun 2003 02:54:33 -0000 1.218
+++ gdbarch.c 4 Jun 2003 18:34:53 -0000
@@ -990,8 +990,8 @@
#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",
@@ -2140,8 +2140,8 @@
/* 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,
@@ -4114,7 +4114,7 @@
}
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)
@@ -4122,7 +4122,7 @@
"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
@@ -4133,7 +4133,7 @@
}
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)
@@ -4141,7 +4141,7 @@
"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
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.188
diff -u -r1.188 gdbarch.h
--- gdbarch.h 2 Jun 2003 02:54:33 -0000 1.188
+++ gdbarch.h 4 Jun 2003 18:34:53 -0000
@@ -1451,32 +1451,32 @@
/* 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. */
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.240
diff -u -r1.240 gdbarch.sh
--- gdbarch.sh 2 Jun 2003 02:54:34 -0000 1.240
+++ gdbarch.sh 4 Jun 2003 18:34:55 -0000
@@ -557,8 +557,8 @@
f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0
f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, 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: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 type *type, int regnum, char *from, char *to:type, regnum, from, to::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
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.151
diff -u -r1.151 i386-tdep.c
--- i386-tdep.c 2 Jun 2003 02:54:35 -0000 1.151
+++ i386-tdep.c 4 Jun 2003 18:34:56 -0000
@@ -1326,52 +1326,55 @@
this is still sloppy. */
static int
-i386_register_convertible (int regnum)
+i386_convert_register_p (int regnum, struct type *type)
{
- return i386_fp_regnum_p (regnum);
+ if (i386_fp_regnum_p (regnum)
+ && TYPE_CODE (type) != TYPE_CODE_FLT)
+ /* Floating point registers have different register and memory
+ representations and hence need converting. */
+ return 1;
+ if (regnum < 3
+ && TYPE_CODE (type) == TYPE_CODE_INT
+ && TYPE_LENGTH (type) == 8)
+ /* A long long in registers, apparently GCC uses a set pair of
+ registers but they are not contigious. */
+ return 1;
+ /* Nothing interesting. */
+ return 0;
}
/* Convert data from raw format for register REGNUM in buffer FROM to
virtual format with type TYPE in buffer TO. */
+/* GCC allocates registers in the following order. */
+static int next_int64_regnum[] = { /*ax,dx,cx,bx*/ 2, 1, 3, };
+
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));
-
- /* 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[MAX_REGISTER_SIZE];
+ /* Read/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 if (regnum < 3)
+ {
+ frame_read_register (frame, regnum, to);
+ frame_read_register (frame, next_int64_regnum[regnum], (char *) to + 4);
}
-
- /* 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);
}
/* Convert data from virtual format with type TYPE in buffer FROM to
raw format for register REGNUM in buffer TO. */
static void
-i386_register_convert_to_raw (struct type *type, int regnum,
- char *from, char *to)
+i386_value_to_register (struct type *type, int regnum, char *from, char *to)
{
- gdb_assert (i386_fp_regnum_p (regnum));
-
- /* 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.");
- memset (to, 0, TYPE_LENGTH (type));
- 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);
@@ -1686,10 +1689,9 @@
/* Call dummy code. */
set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
- set_gdbarch_register_convertible (gdbarch, i386_register_convertible);
- set_gdbarch_register_convert_to_virtual (gdbarch,
- i386_register_convert_to_virtual);
- set_gdbarch_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);
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.207
diff -u -r1.207 mips-tdep.c
--- mips-tdep.c 1 Jun 2003 19:02:19 -0000 1.207
+++ mips-tdep.c 4 Jun 2003 18:34:57 -0000
@@ -634,9 +634,28 @@
TYPE_LENGTH (virtual_type));
}
+static int
+mips_convert_register_p (int regnum, struct type *type)
+{
+ 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_to_value (struct frame_info *frame, int regnum,
+ struct type *type, void *buffer)
+{
+ frame_read_register (frame, regnum + 0, (char *) buffer + 4);
+ frame_read_register (frame, regnum + 1, buffer);
+}
+
void
-mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct type *type, int regnum, char *in, char *out)
{
+#if 0
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
&& REGISTER_RAW_SIZE (regnum) == 4
&& (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
@@ -646,24 +665,9 @@
char temp[4];
memcpy (temp, ((char *)(buffer))+4, 4);
memcpy (((char *)(buffer))+4, (buffer), 4);
- memcpy (((char *)(buffer)), temp, 4);
+ memcpy (((char *)(buffer)), temp, 4);
}
-}
-
-void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
-{
-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);
- }
+#endif
}
/* Return the GDB type object for the "standard" data type
@@ -5961,11 +5965,9 @@
set_gdbarch_deprecated_pop_frame (gdbarch, mips_pop_frame);
set_gdbarch_frame_align (gdbarch, mips_frame_align);
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
- set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
- set_gdbarch_register_convert_to_virtual (gdbarch,
- mips_register_convert_to_virtual);
- set_gdbarch_register_convert_to_raw (gdbarch,
- mips_register_convert_to_raw);
+ set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
set_gdbarch_frameless_function_invocation (gdbarch,
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.109
diff -u -r1.109 valops.c
--- valops.c 14 May 2003 17:43:20 -0000 1.109
+++ valops.c 4 Jun 2003 18:34:58 -0000
@@ -501,10 +501,13 @@
convert FROMVAL's contents now, with result in `raw_buffer',
and set USE_BUFFER to the number of bytes to write. */
+ /* FIXME: Should instead do this in the below switch when it is
+ clear that this really is a lval_register that needs conversion. */
+
if (VALUE_REGNO (toval) >= 0)
{
int regno = VALUE_REGNO (toval);
- if (CONVERT_REGISTER_P (regno))
+ if (CONVERT_REGISTER_P (regno, VALUE_TYPE (toval)))
{
struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
VALUE_TO_REGISTER (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer);
@@ -661,9 +664,11 @@
TYPE_LENGTH (type));
/* Do any conversion necessary when storing this type to
more than one register. */
+#if 0
#ifdef REGISTER_CONVERT_FROM_TYPE
REGISTER_CONVERT_FROM_TYPE (value_reg, type,
(buffer + byte_offset));
+#endif
#endif
}
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE
2003-06-04 19:38 [wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE Andrew Cagney
@ 2003-06-04 21:45 ` Mark Kettenis
2003-06-04 23:05 ` Andrew Cagney
2003-06-06 18:12 ` [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al Andrew Cagney
0 siblings, 2 replies; 15+ messages in thread
From: Mark Kettenis @ 2003-06-04 21:45 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
Andrew Cagney <ac131313@redhat.com> writes:
[snip]
> With this in mind, I'm thinking that REGISTER_TO_TYPE and
> REGISTER_TO_VALUE should be merged. To that end, I can see several ways
> of doing it:
>
> - Don't merge - add REGISTER_TO_TYPE to the architecture vector
>
> - Retain the current logic - just apply REGISTER_TO_VALUE to values
> stored across multiple registers
>
> - Add a frame parameter to REGISTER_TO_VALUE and make it responsible for
> both extracting the bytes from the register[s] and then storing them in
> the ``struct value''.
>
> The last option is interesting, it would let the target draw the value
> from any register based on REGNUM. The i386 with its long-long problem
> might be interested in this (you'll notice in the patch I made an
> attempt at doing this only I didn't see it affect the test results).
>
> Thoughts?
The last option is certainly attractive. The fact that this doesn't
show any improvements in the testsuite, is because there is no test
for `long long' in store.exp. There are tests for small structs there
that will still fail since your implementation of
i386_register_to_value isn't complete; it should also handle 8-byte
strcutures stored in registers. Not just integers.
Anyway, you can leave the i386-specific details to me if you prefer.
Mark
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE
2003-06-04 21:45 ` Mark Kettenis
@ 2003-06-04 23:05 ` Andrew Cagney
2003-06-06 18:12 ` [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al Andrew Cagney
1 sibling, 0 replies; 15+ messages in thread
From: Andrew Cagney @ 2003-06-04 23:05 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Andrew Cagney <ac131313@redhat.com> writes:
>
> [snip]
>
>
>> With this in mind, I'm thinking that REGISTER_TO_TYPE and
>> REGISTER_TO_VALUE should be merged. To that end, I can see several ways
>> of doing it:
>>
>> - Don't merge - add REGISTER_TO_TYPE to the architecture vector
>>
>> - Retain the current logic - just apply REGISTER_TO_VALUE to values
>> stored across multiple registers
>>
>> - Add a frame parameter to REGISTER_TO_VALUE and make it responsible for
>> both extracting the bytes from the register[s] and then storing them in
>> the ``struct value''.
>>
>> The last option is interesting, it would let the target draw the value
>> from any register based on REGNUM. The i386 with its long-long problem
>> might be interested in this (you'll notice in the patch I made an
>> attempt at doing this only I didn't see it affect the test results).
>>
>> Thoughts?
>
>
> The last option is certainly attractive. The fact that this doesn't
> show any improvements in the testsuite, is because there is no test
> for `long long' in store.exp.
What about reading long long values? Nothing there either? The
changes, as they stand, don't touch the path used when storing (note the
#if 0 in the patch ....).
> There are tests for small structs there
> that will still fail since your implementation of
> i386_register_to_value isn't complete; it should also handle 8-byte
> strcutures stored in registers. Not just integers.
>
> Anyway, you can leave the i386-specific details to me if you prefer.
M'kay.
Andrew
^ permalink raw reply [flat|nested] 15+ messages in thread
* [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-04 21:45 ` Mark Kettenis
2003-06-04 23:05 ` Andrew Cagney
@ 2003-06-06 18:12 ` Andrew Cagney
2003-06-08 16:43 ` Mark Kettenis
1 sibling, 1 reply; 15+ messages in thread
From: Andrew Cagney @ 2003-06-06 18:12 UTC (permalink / raw)
To: Mark Kettenis, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 629 bytes --]
Mark,
I've created the branch: cagney_convert-20030606-branch and committed
the attached. It's different from the original in the following ways:
- REGISTER_TO_VALUE and VALUE_TO_REGISTER take the full ``struct value''
instead of ``struct type'' and a ``void *buf''. Those methods are now
entirely responsible for converting a register to/from the specified value.
- Adds the possibly contraversal put_frame_register method. It turned
out that at least three functions contained the code sequence: find
REGNUM's true location, store the value in that location.
Feel free to try to get the i386 stuff working.
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 36219 bytes --]
2003-06-06 Andrew Cagney <cagney@redhat.com>
* frame.h (put_frame_register): Declare.
* frame.c (put_frame_register): New function.
* arch-utils.c: Include "gdbcore.h".
(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.
* Makefile.in (arch-utils.o): Update dependencies.
* 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.
* gdbarch.sh (CONVERT_REGISTER_P): Add "type" parameter.
(REGISTER_TO_VALUE, VALUE_TO_REGISTER): Replace "type", "from" and
"to" parameters with "frame" and "value".
* gdbarch.h, gdbarch.c: Re-generate.
* 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.
* 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.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.391
diff -u -r1.391 Makefile.in
--- Makefile.in 5 Jun 2003 20:59:15 -0000 1.391
+++ Makefile.in 6 Jun 2003 17:36:01 -0000
@@ -1539,7 +1539,7 @@
$(inferior_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
$(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(annotate_h) \
$(gdb_string_h) $(regcache_h) $(gdb_assert_h) $(sim_regno_h) \
- $(version_h) $(floatformat_h)
+ $(version_h) $(floatformat_h) $(gdbcore_h)
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h)
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.83
diff -u -r1.83 arch-utils.c
--- arch-utils.c 15 May 2003 22:58:36 -0000 1.83
+++ arch-utils.c 6 Jun 2003 17:36:02 -0000
@@ -47,6 +47,7 @@
#include "version.h"
#include "floatformat.h"
+#include "gdbcore.h"
/* Implementation of extract return value that grubs around in the
register cache. */
@@ -440,23 +441,54 @@
}
int
-legacy_convert_register_p (int regnum)
+legacy_convert_register_p (int regnum, struct type *type)
{
return 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 value *v)
{
- REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+ char from[MAX_REGISTER_SIZE];
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ frame_register (frame, regnum, &optim, &lval, &addr, &realnum, from);
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, VALUE_TYPE (v), from,
+ VALUE_CONTENTS_RAW (v));
+ VALUE_LVAL (v) = lval;
+ VALUE_REGNO (v) = realnum;
+ VALUE_ADDRESS (v) = addr;
+ /* Note: This function is just trying to keep old code alive, don't
+ let it handle anything other than a few obvious cases. */
+ gdb_assert (lval == lval_register || lval == lval_memory);
+ VALUE_OPTIMIZED_OUT (v) = optim;
}
void
-legacy_value_to_register (struct type *type, int regnum,
- char *from, char *to)
+legacy_value_to_register (struct frame_info *frame, struct value *v)
{
- REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ char to[MAX_REGISTER_SIZE];
+ REGISTER_CONVERT_TO_RAW (VALUE_TYPE (v), VALUE_REGNO (v),
+ VALUE_CONTENTS (v), to);
+ switch (VALUE_LVAL (v))
+ {
+ case lval_register:
+ /* FIXME: How to get from the frame to the, several levels
+ inner, regcache? */
+ regcache_cooked_write (current_regcache, VALUE_REGNO (v), to);
+ break;
+ case lval_memory:
+ write_memory (VALUE_ADDRESS (v), to,
+ register_size (gdbarch, (VALUE_REGNO (v))));
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "Unhandled lval %d",
+ (int) VALUE_LVAL (v));
+ }
}
\f
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.46
diff -u -r1.46 arch-utils.h
--- arch-utils.h 15 May 2003 22:58:36 -0000 1.46
+++ arch-utils.h 6 Jun 2003 17:36:02 -0000
@@ -165,9 +165,9 @@
(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 value *v);
+extern void legacy_value_to_register (struct frame_info *frame, struct value *v);
/* For compatibility with older architectures, returns
(LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.58
diff -u -r1.58 findvar.c
--- findvar.c 5 Jun 2003 20:59:16 -0000 1.58
+++ findvar.c 6 Jun 2003 17:36:02 -0000
@@ -624,145 +624,76 @@
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))
+ {
+ int realnum;
+ int optim;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ /* 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, v);
+ }
+ 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 +712,29 @@
{
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;
- }
-
- /* 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);
+ 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);
}
-
return v;
}
+
\f
/* Given a struct symbol for a variable or function,
and a stack frame id,
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.117
diff -u -r1.117 frame.c
--- frame.c 3 Jun 2003 18:53:37 -0000 1.117
+++ frame.c 6 Jun 2003 17:36:07 -0000
@@ -674,6 +674,36 @@
}
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
generic_unwind_get_saved_register (char *raw_buffer,
int *optimizedp,
CORE_ADDR *addrp,
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.96
diff -u -r1.96 frame.h
--- frame.h 3 Jun 2003 18:53:37 -0000 1.96
+++ frame.h 6 Jun 2003 17:36:07 -0000
@@ -325,6 +325,12 @@
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
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.218
diff -u -r1.218 gdbarch.c
--- gdbarch.c 2 Jun 2003 02:54:33 -0000 1.218
+++ gdbarch.c 6 Jun 2003 17:36:09 -0000
@@ -990,8 +990,8 @@
#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",
@@ -2140,8 +2140,8 @@
/* 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, v)",
+ XSTRING (REGISTER_TO_VALUE (frame, regnum, v)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@@ -2636,8 +2636,8 @@
/* 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, v)",
+ XSTRING (VALUE_TO_REGISTER (frame, v)));
#endif
if (GDB_MULTI_ARCH)
fprintf_unfiltered (file,
@@ -4114,7 +4114,7 @@
}
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)
@@ -4122,7 +4122,7 @@
"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
@@ -4133,7 +4133,7 @@
}
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 value *v)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->register_to_value == 0)
@@ -4141,7 +4141,7 @@
"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, v);
}
void
@@ -4152,7 +4152,7 @@
}
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, struct value *v)
{
gdb_assert (gdbarch != NULL);
if (gdbarch->value_to_register == 0)
@@ -4160,7 +4160,7 @@
"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, v);
}
void
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.188
diff -u -r1.188 gdbarch.h
--- gdbarch.h 2 Jun 2003 02:54:33 -0000 1.188
+++ gdbarch.h 6 Jun 2003 17:36:10 -0000
@@ -1451,47 +1451,47 @@
/* 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, v) (legacy_register_to_value (frame, regnum, v))
#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 value *v);
+extern void gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct value *v);
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, v) (gdbarch_register_to_value (current_gdbarch, frame, regnum, v))
#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, v) (legacy_value_to_register (frame, v))
#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, struct value *v);
+extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, struct value *v);
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, v) (gdbarch_value_to_register (current_gdbarch, frame, v))
#endif
/* Default (function) for non- multi-arch platforms. */
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.240
diff -u -r1.240 gdbarch.sh
--- gdbarch.sh 2 Jun 2003 02:54:34 -0000 1.240
+++ gdbarch.sh 6 Jun 2003 17:36:12 -0000
@@ -557,9 +557,9 @@
f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0
f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, 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 value *v:frame, regnum, v::0:legacy_register_to_value::0
+f:1:VALUE_TO_REGISTER:void:value_to_register:struct frame_info *frame, struct value *v:frame, v::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
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.207
diff -u -r1.207 mips-tdep.c
--- mips-tdep.c 1 Jun 2003 19:02:19 -0000 1.207
+++ mips-tdep.c 6 Jun 2003 17:36:15 -0000
@@ -634,36 +634,33 @@
TYPE_LENGTH (virtual_type));
}
+static int
+mips_convert_register_p (int regnum, struct type *type)
+{
+ 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_to_type (int regnum, struct type *type, char *buffer)
+mips_register_to_value (struct frame_info *frame, int regnum,
+ struct value *v)
{
- 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, VALUE_CONTENTS_RAW (v) + 4);
+ frame_read_register (frame, regnum + 1, VALUE_CONTENTS_RAW (v) + 0);
+ VALUE_LVAL (v) = lval_reg_frame_relative;
+ VALUE_FRAME_ID (v) = get_frame_id (frame);
+ VALUE_FRAME_REGNUM (v) = regnum;
}
void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct frame_info *frame, struct value *v)
{
-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);
- }
+ int regnum = VALUE_FRAME_REGNUM (v);
+ put_frame_register (frame, regnum + 0, VALUE_CONTENTS (v) + 4);
+ put_frame_register (frame, regnum + 1, VALUE_CONTENTS (v) + 0);
}
/* Return the GDB type object for the "standard" data type
@@ -5966,6 +5963,9 @@
mips_register_convert_to_virtual);
set_gdbarch_register_convert_to_raw (gdbarch,
mips_register_convert_to_raw);
+ set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
set_gdbarch_frameless_function_invocation (gdbarch,
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.110
diff -u -r1.110 valops.c
--- valops.c 5 Jun 2003 20:59:16 -0000 1.110
+++ valops.c 6 Jun 2003 17:36:16 -0000
@@ -496,22 +496,6 @@
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. */
@@ -585,17 +569,8 @@
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)
@@ -611,92 +586,78 @@
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))
- {
- modify_field (buffer + byte_offset,
- value_as_long (fromval),
- VALUE_BITPOS (toval), VALUE_BITSIZE (toval));
- }
- else if (use_buffer)
+ if (CONVERT_REGISTER_P (VALUE_REGNO (toval), VALUE_TYPE (toval)))
{
- 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,
+ convert FROMVAL's contents now, with result in
+ `raw_buffer', and set USE_BUFFER to the number of bytes
+ to write. Let VALUE_TO_REGISTER sort out the mess. */
+ VALUE_TO_REGISTER (frame, 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
- }
-
- /* 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;
+ /* 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;
+
+ /* 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);
- /* Just find out where to put it. */
- frame_register (frame, regno, &optim, &lval, &addr, &realnum,
- NULL);
+ /* 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);
- 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));
+ /* 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
- error ("Attempt to assign to an unmodifiable value.");
- }
+ 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.");
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-06 18:12 ` [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al Andrew Cagney
@ 2003-06-08 16:43 ` Mark Kettenis
2003-06-08 17:15 ` Andrew Cagney
0 siblings, 1 reply; 15+ messages in thread
From: Mark Kettenis @ 2003-06-08 16:43 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
Date: Fri, 06 Jun 2003 14:12:23 -0400
From: Andrew Cagney <ac131313@redhat.com>
Mark,
I've created the branch: cagney_convert-20030606-branch and committed
the attached. It's different from the original in the following ways:
- REGISTER_TO_VALUE and VALUE_TO_REGISTER take the full ``struct value''
instead of ``struct type'' and a ``void *buf''. Those methods are now
entirely responsible for converting a register to/from the specified value.
There is defenitely something wrong here. The first thing is that in
valops.c:value_assign() you call CONVERT_REGISTER_P as follows:
+ if (CONVERT_REGISTER_P (VALUE_REGNO (toval), VALUE_TYPE (toval)))
This is wrong for the lval_reg_frame_relative case. Replacing
`VALUE_REGNO (toval)' with `value_reg' seems the obvious solution, and
indeed, this makes us execute the following line:
+ VALUE_TO_REGISTER (frame, fromval);
This is strange. Which register should FROMVAL be stored in? That
information is contained in TOVAL. Passing TOVAL here is also wrong,
since the contents of the value are contained in FROMVAL. A possible
solution is passing the register number to VALUE_TO_REGISTER. Another
solution is assigning the contents of FROMVAL to (a copy of) TOVAL and
pass the latter to VALUE_TO_REGISTER. This seems to be what you had
in mind when you wrote the MIPS implementation of VALUE_TO_REGISTER.
Besides this issue I have a few other comments on these interfaces.
1. I think it is a good idea to ask the following question again: Why
do we have both lval_register and lval_reg_frame_relative?
Both seem to deal with values stored in registers. Yes, these can
be frame-relative or not. But wouldn't it be better to let
VALUE_FRAME_ID() indicate this? A value of null_frame_id would
then indicate a global register variable.
I may be mistaken, but I think this has consequences for the
REGISTER_TO_VALUE interface. Instead of an interface that
constructs the complete value, I think we need an interface that
just fetches the contents from the appropriate registers; something
that is similar to what we have now.
2. What do we guarantee about the `struct value' that is passed to
VALUE_TO_REGISTER? That it is created by REGISTER_TO_VALUE?
- Adds the possibly contraversal put_frame_register method. It turned
out that at least three functions contained the code sequence: find
REGNUM's true location, store the value in that location.
Nothing against the function, but can we try to keep the naming of the
register functions a bit more symmetrical?
Anyway, I don't think you should check this in just yet. It
definitely needs some more discussion.
Mark
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-08 16:43 ` Mark Kettenis
@ 2003-06-08 17:15 ` Andrew Cagney
2003-06-08 22:11 ` Andrew Cagney
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Cagney @ 2003-06-08 17:15 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Date: Fri, 06 Jun 2003 14:12:23 -0400
> From: Andrew Cagney <ac131313@redhat.com>
>
> Mark,
>
> I've created the branch: cagney_convert-20030606-branch and committed
> the attached. It's different from the original in the following ways:
>
> - REGISTER_TO_VALUE and VALUE_TO_REGISTER take the full ``struct value''
> instead of ``struct type'' and a ``void *buf''. Those methods are now
> entirely responsible for converting a register to/from the specified value.
>
> There is defenitely something wrong here. The first thing is that in
> valops.c:value_assign() you call CONVERT_REGISTER_P as follows:
I'm not suprised, nothing in the testsuite was testing it.
> + if (CONVERT_REGISTER_P (VALUE_REGNO (toval), VALUE_TYPE (toval)))
>
> This is wrong for the lval_reg_frame_relative case. Replacing
> `VALUE_REGNO (toval)' with `value_reg' seems the obvious solution, and
> indeed, this makes us execute the following line:
>
> + VALUE_TO_REGISTER (frame, fromval);
>
> This is strange. Which register should FROMVAL be stored in? That
> information is contained in TOVAL. Passing TOVAL here is also wrong,
> since the contents of the value are contained in FROMVAL. A possible
> solution is passing the register number to VALUE_TO_REGISTER. Another
> solution is assigning the contents of FROMVAL to (a copy of) TOVAL and
> pass the latter to VALUE_TO_REGISTER. This seems to be what you had
> in mind when you wrote the MIPS implementation of VALUE_TO_REGISTER.
>
> Besides this issue I have a few other comments on these interfaces.
>
> 1. I think it is a good idea to ask the following question again: Why
> do we have both lval_register and lval_reg_frame_relative?
lval_memory and lval_register are important when it comes to storing
registers, but not when tracking variables. A variable should really
only have lval_reg_frame_relative. Tried it though and things ``broke''.
> Both seem to deal with values stored in registers. Yes, these can
> be frame-relative or not. But wouldn't it be better to let
> VALUE_FRAME_ID() indicate this? A value of null_frame_id would
> then indicate a global register variable.
Yep, ref: Use of lval_register?
http://sources.redhat.com/ml/gdb/2003-06/msg00065.html
In theory, it's always frame-relative.
> I may be mistaken, but I think this has consequences for the
> REGISTER_TO_VALUE interface. Instead of an interface that
> constructs the complete value, I think we need an interface that
> just fetches the contents from the appropriate registers; something
> that is similar to what we have now.
>
> 2. What do we guarantee about the `struct value' that is passed to
> VALUE_TO_REGISTER? That it is created by REGISTER_TO_VALUE?
The code guarentee that REGISTER_CONVERT_P holds and, by implication,
REGISTER_TO_VALUE was used to construct it.
>
> - Adds the possibly contraversal put_frame_register method. It turned
> out that at least three functions contained the code sequence: find
> REGNUM's true location, store the value in that location.
>
> Nothing against the function, but can we try to keep the naming of the
> register functions a bit more symmetrical?
I do. Its the frame oposites (get_frame_xxxxx) that are the problem and
need some savage renaming.
> Anyway, I don't think you should check this in just yet. It
> definitely needs some more discussion.
I was assuming you were going to fix it (or at least the write side :-)
The ``obvious'' interfaces were:
register_to_value (frame, regnum, type, buffer)
value_to_register (frame, regnum, type, buffer)
but that tripped up on something (now what ...?). Dig dig. Notice how,
to preserve existing behavior, legacy_register_to_value saves the
location based on what frame_register returns. We'd have to switch to
lval_reg_frame_relative.
Andrew
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-08 17:15 ` Andrew Cagney
@ 2003-06-08 22:11 ` Andrew Cagney
2003-06-08 22:51 ` Mark Kettenis
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Andrew Cagney @ 2003-06-08 22:11 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Mark Kettenis, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 583 bytes --]
Ok, I've changed the branch to:
> The ``obvious'' interfaces were:
>
> register_to_value (frame, regnum, type, buffer)
> value_to_register (frame, regnum, type, buffer)
>
> but that tripped up on something (now what ...?). Dig dig. Notice how, to preserve existing behavior, legacy_register_to_value saves the location based on what frame_register returns. We'd have to switch to lval_reg_frame_relative.
And this time it appears to be going better. I'll try to attribute it
to VALUE_FRAME_ID and the use of put_frame_register (neither of which I
did last time).
Andrew
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 27814 bytes --]
2003-06-06 Andrew Cagney <cagney@redhat.com>
* frame.h (put_frame_register): Declare.
* frame.c (put_frame_register): New function.
* arch-utils.c: Include "gdbcore.h".
(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.
* Makefile.in (arch-utils.o): Update dependencies.
* 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.
* 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.
* 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.
* 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.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.391
retrieving revision 1.391.2.1
diff -u -r1.391 -r1.391.2.1
--- Makefile.in 5 Jun 2003 20:59:15 -0000 1.391
+++ Makefile.in 6 Jun 2003 18:02:26 -0000 1.391.2.1
@@ -1539,7 +1539,7 @@
$(inferior_h) $(symtab_h) $(frame_h) $(inferior_h) $(breakpoint_h) \
$(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(annotate_h) \
$(gdb_string_h) $(regcache_h) $(gdb_assert_h) $(sim_regno_h) \
- $(version_h) $(floatformat_h)
+ $(version_h) $(floatformat_h) $(gdbcore_h)
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h)
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.83
diff -u -r1.83 arch-utils.c
--- arch-utils.c 15 May 2003 22:58:36 -0000 1.83
+++ arch-utils.c 8 Jun 2003 22:02:33 -0000
@@ -47,6 +47,7 @@
#include "version.h"
#include "floatformat.h"
+#include "gdbcore.h"
/* Implementation of extract return value that grubs around in the
register cache. */
@@ -440,23 +441,29 @@
}
int
-legacy_convert_register_p (int regnum)
+legacy_convert_register_p (int regnum, struct type *type)
{
return 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);
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));
REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
+ put_frame_register (frame, regnum, to);
}
\f
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.46
diff -u -r1.46 arch-utils.h
--- arch-utils.h 15 May 2003 22:58:36 -0000 1.46
+++ arch-utils.h 8 Jun 2003 22:02:33 -0000
@@ -165,9 +165,11 @@
(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
Index: findvar.c
===================================================================
RCS file: /cvs/src/src/gdb/findvar.c,v
retrieving revision 1.58
diff -u -r1.58 findvar.c
--- findvar.c 5 Jun 2003 20:59:16 -0000 1.58
+++ findvar.c 8 Jun 2003 22:02:36 -0000
@@ -624,145 +624,75 @@
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_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;
- }
-
- /* 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);
+ 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);
}
-
return v;
}
+
\f
/* Given a struct symbol for a variable or function,
and a stack frame id,
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.117
retrieving revision 1.117.2.1
diff -u -r1.117 -r1.117.2.1
--- frame.c 3 Jun 2003 18:53:37 -0000 1.117
+++ frame.c 6 Jun 2003 18:02:28 -0000 1.117.2.1
@@ -674,6 +674,36 @@
}
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
generic_unwind_get_saved_register (char *raw_buffer,
int *optimizedp,
CORE_ADDR *addrp,
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.96
retrieving revision 1.96.2.1
diff -u -r1.96 -r1.96.2.1
--- frame.h 3 Jun 2003 18:53:37 -0000 1.96
+++ frame.h 6 Jun 2003 18:02:29 -0000 1.96.2.1
@@ -325,6 +325,12 @@
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
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.240
diff -u -r1.240 gdbarch.sh
--- gdbarch.sh 2 Jun 2003 02:54:34 -0000 1.240
+++ gdbarch.sh 8 Jun 2003 22:02:57 -0000
@@ -557,9 +557,9 @@
f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0
f:2:REGISTER_CONVERT_TO_RAW:void:register_convert_to_raw:struct type *type, int regnum, 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
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.207
diff -u -r1.207 mips-tdep.c
--- mips-tdep.c 1 Jun 2003 19:02:19 -0000 1.207
+++ mips-tdep.c 8 Jun 2003 22:03:03 -0000
@@ -634,36 +634,30 @@
TYPE_LENGTH (virtual_type));
}
+static int
+mips_convert_register_p (int regnum, struct type *type)
+{
+ 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_to_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_register_convert_from_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct frame_info *frame, int regnum,
+ struct type *type, const void *from)
{
-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);
- }
+ put_frame_register (frame, regnum + 0, (const char *) + 4);
+ put_frame_register (frame, regnum + 1, (const char *) + 0);
}
/* Return the GDB type object for the "standard" data type
@@ -5966,6 +5960,9 @@
mips_register_convert_to_virtual);
set_gdbarch_register_convert_to_raw (gdbarch,
mips_register_convert_to_raw);
+ set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
+ set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
+ set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
set_gdbarch_frameless_function_invocation (gdbarch,
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.110
diff -u -r1.110 valops.c
--- valops.c 5 Jun 2003 20:59:16 -0000 1.110
+++ valops.c 8 Jun 2003 22:03:05 -0000
@@ -496,22 +496,6 @@
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. */
@@ -585,17 +569,8 @@
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)
@@ -611,92 +586,78 @@
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))
- {
- 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 (VALUE_LVAL (toval) == lval_reg_frame_relative
+ && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval),
+ VALUE_TYPE (toval)))
+ {
+ /* 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),
+ VALUE_TYPE (toval), VALUE_CONTENTS (toval));
}
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
- }
-
- /* 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;
+ /* 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;
+
+ /* 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);
- /* Just find out where to put it. */
- frame_register (frame, regno, &optim, &lval, &addr, &realnum,
- NULL);
+ /* 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);
- 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));
+ /* 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
- error ("Attempt to assign to an unmodifiable value.");
- }
+ 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.");
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-08 22:11 ` Andrew Cagney
@ 2003-06-08 22:51 ` Mark Kettenis
2003-06-09 0:22 ` Andrew Cagney
2003-06-09 9:38 ` Mark Kettenis
2003-06-09 10:26 ` Mark Kettenis
2 siblings, 1 reply; 15+ messages in thread
From: Mark Kettenis @ 2003-06-08 22:51 UTC (permalink / raw)
To: ac131313; +Cc: ac131313, gdb-patches
Date: Sun, 08 Jun 2003 18:10:29 -0400
From: Andrew Cagney <ac131313@redhat.com>
Ok, I've changed the branch to:
> The ``obvious'' interfaces were:
>
> register_to_value (frame, regnum, type, buffer)
> value_to_register (frame, regnum, type, buffer)
And what do these functions do if the register is unavailable in a
certain frame? That shouldn't happen if we have complete debug
information, but unfortunately we almost certainly don't have that.
Should this be reported to the user or not? Should we set
VALUE_OPTIMIZED_OUT, just as we do for registers that don't need
conversion? If so, we probably need a return value that indicates
whether the conversion was successfull.
> but that tripped up on something (now what ...?). Dig dig.
> Notice how, to preserve existing behavior,
> legacy_register_to_value saves the location based on what
> frame_register returns. We'd have to switch to
> lval_reg_frame_relative.
And this time it appears to be going better. I'll try to attribute it
to VALUE_FRAME_ID and the use of put_frame_register (neither of which I
did last time).
Great!
Mark
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-08 22:51 ` Mark Kettenis
@ 2003-06-09 0:22 ` Andrew Cagney
2003-06-09 9:35 ` Mark Kettenis
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Cagney @ 2003-06-09 0:22 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> And what do these functions do if the register is unavailable in a
> certain frame? That shouldn't happen if we have complete debug
> information, but unfortunately we almost certainly don't have that.
> Should this be reported to the user or not? Should we set
> VALUE_OPTIMIZED_OUT, just as we do for registers that don't need
> conversion? If so, we probably need a return value that indicates
> whether the conversion was successfull.
I've got into the habit of ignoring OPTIMIZED_OUT, for registers it's
always cleared (well ignoring the recent CFI stuff). It was added
between 3.5 and 3.93 but for no apparent reason (at least for
registers). The ChangeLog's are not very enlightenting and this
pre-dates Cygnus CVS.
Anyway, the question of what to do when the register's value can't be
found has been largely ignored. I'm thinking that throwing an error
would be a safer strategy - there is too much code ignoring register
fetches and I don't think we're going to be auditing it soon.
Andrew
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-09 0:22 ` Andrew Cagney
@ 2003-06-09 9:35 ` Mark Kettenis
2003-06-09 14:38 ` Andrew Cagney
0 siblings, 1 reply; 15+ messages in thread
From: Mark Kettenis @ 2003-06-09 9:35 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
Date: Sun, 08 Jun 2003 20:22:14 -0400
From: Andrew Cagney <ac131313@redhat.com>
> And what do these functions do if the register is unavailable in a
> certain frame? That shouldn't happen if we have complete debug
> information, but unfortunately we almost certainly don't have that.
> Should this be reported to the user or not? Should we set
> VALUE_OPTIMIZED_OUT, just as we do for registers that don't need
> conversion? If so, we probably need a return value that indicates
> whether the conversion was successfull.
I've got into the habit of ignoring OPTIMIZED_OUT, for registers it's
always cleared (well ignoring the recent CFI stuff). It was added
between 3.5 and 3.93 but for no apparent reason (at least for
registers). The ChangeLog's are not very enlightenting and this
pre-dates Cygnus CVS.
Well, most debugging info isn't expressive enough to indicate which
registers have been saved, and which registers haven't. Therefore
most unwinders pretend they can always find the register, and do so by
returning the value from the next frame.
Anyway, the question of what to do when the register's value can't be
found has been largely ignored. I'm thinking that throwing an error
would be a safer strategy - there is too much code ignoring register
fetches and I don't think we're going to be auditing it soon.
Indeed, GDB depends on the frame unwinder always returning a value for
its registers. However for the sake of printing variables stored in
registers it seems that setting OPTIMIZED_OUT makes sense if we know
for certain that a the register has been thrashed. It makes
valprint.c:value_print() print "<value optimized out>". The problem
with printing an error message from REGISTER_TO_VALUE() is keeping the
error messages uniform. However, in some cases it might be more
appropriate to print a warning instead of an error, for example if the
register hasn't been saved, but if we cannot tell whether it has been
thrashed yet.
However, I can live with the current status quo.
Mark
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-08 22:11 ` Andrew Cagney
2003-06-08 22:51 ` Mark Kettenis
@ 2003-06-09 9:38 ` Mark Kettenis
2003-06-09 14:20 ` Andrew Cagney
2003-06-09 10:26 ` Mark Kettenis
2 siblings, 1 reply; 15+ messages in thread
From: Mark Kettenis @ 2003-06-09 9:38 UTC (permalink / raw)
To: ac131313; +Cc: ac131313, gdb-patches
Date: Sun, 08 Jun 2003 18:10:29 -0400
From: Andrew Cagney <ac131313@redhat.com>
Ok, I've changed the branch to:
> The ``obvious'' interfaces were:
>
> register_to_value (frame, regnum, type, buffer)
> value_to_register (frame, regnum, type, buffer)
>
> but that tripped up on something (now what ...?). Dig dig.
> Notice how, to preserve existing behavior,
> legacy_register_to_value saves the location based on what
> frame_register returns. We'd have to switch to
> lval_reg_frame_relative.
And this time it appears to be going better. I'll try to attribute it
to VALUE_FRAME_ID and the use of put_frame_register (neither of which I
did last time).
Andrew, the attached fixes writing values into registers. OK to check
this in on the branch?
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* valops.c (value_assign): Assign contents of FROMVAL instead of
TOVAL.
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.110.2.2
diff -u -p -r1.110.2.2 valops.c
--- valops.c 8 Jun 2003 22:14:42 -0000 1.110.2.2
+++ valops.c 9 Jun 2003 09:02:27 -0000
@@ -588,13 +588,12 @@ value_assign (struct value *toval, struc
error ("Value being assigned to is no longer active.");
if (VALUE_LVAL (toval) == lval_reg_frame_relative
- && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval),
- VALUE_TYPE (toval)))
+ && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type))
{
/* 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),
- VALUE_TYPE (toval), VALUE_CONTENTS (toval));
+ type, VALUE_CONTENTS (fromval));
}
else
{
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-08 22:11 ` Andrew Cagney
2003-06-08 22:51 ` Mark Kettenis
2003-06-09 9:38 ` Mark Kettenis
@ 2003-06-09 10:26 ` Mark Kettenis
2 siblings, 0 replies; 15+ messages in thread
From: Mark Kettenis @ 2003-06-09 10:26 UTC (permalink / raw)
To: ac131313; +Cc: ac131313, gdb-patches
Andrew,
I checked in the following obvious fix on the branch.
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* mips-tdep.c (mips_value_to_register): Fix.
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.207.2.2
diff -u -p -r1.207.2.2 mips-tdep.c
--- mips-tdep.c 8 Jun 2003 22:14:42 -0000 1.207.2.2
+++ mips-tdep.c 9 Jun 2003 10:25:25 -0000
@@ -656,8 +656,8 @@ 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 *) + 4);
- put_frame_register (frame, regnum + 1, (const char *) + 0);
+ 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
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-09 9:38 ` Mark Kettenis
@ 2003-06-09 14:20 ` Andrew Cagney
2003-06-09 17:43 ` Mark Kettenis
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Cagney @ 2003-06-09 14:20 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Date: Sun, 08 Jun 2003 18:10:29 -0400
> From: Andrew Cagney <ac131313@redhat.com>
>
> Ok, I've changed the branch to:
>
> > The ``obvious'' interfaces were:
> >
> > register_to_value (frame, regnum, type, buffer)
> > value_to_register (frame, regnum, type, buffer)
> >
> > but that tripped up on something (now what ...?). Dig dig.
> > Notice how, to preserve existing behavior,
> > legacy_register_to_value saves the location based on what
> > frame_register returns. We'd have to switch to
> > lval_reg_frame_relative.
>
> And this time it appears to be going better. I'll try to attribute it
> to VALUE_FRAME_ID and the use of put_frame_register (neither of which I
> did last time).
>
> Andrew, the attached fixes writing values into registers. OK to check
> this in on the branch?
Yep, thanks!
Andrew
> Index: ChangeLog
> from Mark Kettenis <kettenis@gnu.org>
>
> * valops.c (value_assign): Assign contents of FROMVAL instead of
> TOVAL.
>
> Index: valops.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/valops.c,v
> retrieving revision 1.110.2.2
> diff -u -p -r1.110.2.2 valops.c
> --- valops.c 8 Jun 2003 22:14:42 -0000 1.110.2.2
> +++ valops.c 9 Jun 2003 09:02:27 -0000
> @@ -588,13 +588,12 @@ value_assign (struct value *toval, struc
> error ("Value being assigned to is no longer active.");
>
> if (VALUE_LVAL (toval) == lval_reg_frame_relative
> - && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval),
> - VALUE_TYPE (toval)))
> + && CONVERT_REGISTER_P (VALUE_FRAME_REGNUM (toval), type))
> {
> /* 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),
> - VALUE_TYPE (toval), VALUE_CONTENTS (toval));
> + type, VALUE_CONTENTS (fromval));
> }
> else
> {
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-09 9:35 ` Mark Kettenis
@ 2003-06-09 14:38 ` Andrew Cagney
0 siblings, 0 replies; 15+ messages in thread
From: Andrew Cagney @ 2003-06-09 14:38 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Anyway, the question of what to do when the register's value can't be
> found has been largely ignored. I'm thinking that throwing an error
> would be a safer strategy - there is too much code ignoring register
> fetches and I don't think we're going to be auditing it soon.
>
> Indeed, GDB depends on the frame unwinder always returning a value for
> its registers. However for the sake of printing variables stored in
> registers it seems that setting OPTIMIZED_OUT makes sense if we know
> for certain that a the register has been thrashed. It makes
> valprint.c:value_print() print "<value optimized out>". The problem
> with printing an error message from REGISTER_TO_VALUE() is keeping the
> error messages uniform. However, in some cases it might be more
> appropriate to print a warning instead of an error, for example if the
> register hasn't been saved, but if we cannot tell whether it has been
> thrashed yet.
>
> However, I can live with the current status quo.
Well, the status quo is that GDB doesn't have a story :-( GDB throws an
error for some values (memory read failures), returns bogus values for
others (register not available), and sets optimized out for more.
As a pie in the sky, would printing better messages help, vis:
<optimized out>
or
<register r10 unavailable>
or
<memory error at 0x1234>
or
<register r11 invalid>
What of the user interface, should it expect to be able to catch such
errors?
Andrew
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al.
2003-06-09 14:20 ` Andrew Cagney
@ 2003-06-09 17:43 ` Mark Kettenis
0 siblings, 0 replies; 15+ messages in thread
From: Mark Kettenis @ 2003-06-09 17:43 UTC (permalink / raw)
To: ac131313; +Cc: gdb-patches
Date: Mon, 09 Jun 2003 10:20:44 -0400
From: Andrew Cagney <ac131313@redhat.com>
> Andrew, the attached fixes writing values into registers. OK to check
> this in on the branch?
Yep, thanks!
Checked in now.
Mark
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2003-06-09 17:43 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-04 19:38 [wip/rfc] Merge REGISTER_TO_VALUE and REGISTER_TO_TYPE Andrew Cagney
2003-06-04 21:45 ` Mark Kettenis
2003-06-04 23:05 ` Andrew Cagney
2003-06-06 18:12 ` [cagney_convert-20030606-branch] Add value to REGISTER_TO_VALUE et.al Andrew Cagney
2003-06-08 16:43 ` Mark Kettenis
2003-06-08 17:15 ` Andrew Cagney
2003-06-08 22:11 ` Andrew Cagney
2003-06-08 22:51 ` Mark Kettenis
2003-06-09 0:22 ` Andrew Cagney
2003-06-09 9:35 ` Mark Kettenis
2003-06-09 14:38 ` Andrew Cagney
2003-06-09 9:38 ` Mark Kettenis
2003-06-09 14:20 ` Andrew Cagney
2003-06-09 17:43 ` Mark Kettenis
2003-06-09 10:26 ` Mark Kettenis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox