* [RFC 1/5] Lazy register values
@ 2008-03-31 22:11 Daniel Jacobowitz
2008-04-04 19:29 ` Ulrich Weigand
0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-03-31 22:11 UTC (permalink / raw)
To: gdb-patches
This patch allows a register value to be lazy. Lazy register values
are created by value_of_register_lazy and fetched by value_fetch_lazy,
like lazy memory values. I went through every check of value_lazy and
updated the ones which assumed this implied memory; the others guard
calls to value_fetch_lazy, which is still correct.
--
Daniel Jacobowitz
CodeSourcery
2008-03-31 Daniel Jacobowitz <dan@codesourcery.com>
* ada-lang.c (ada_value_primitive_packed_val): Only check
value_lazy for memory lvals.
* findvar.c (value_of_register_lazy): New function.
(locate_var_value): Only check value_lazy for memory lvals.
* valarith.c (value_subscripted_rvalue): Likewise.
* valops.c (value_fetch_lazy): Handle both memory and register
lvals.
(search_struct_field, value_slice): Only check value_lazy for memory
lvals.
* value.c (struct value): Update comment for lazy.
(value_primitive_field): Only check value_lazy for memory lvals.
* value.h (value_lazy): Update comment.
(value_of_register_lazy): Declare.
---
gdb/ada-lang.c | 2 +-
gdb/findvar.c | 26 +++++++++++++++++++++++++-
gdb/valarith.c | 2 +-
gdb/valops.c | 40 +++++++++++++++++++++++++++++++++-------
gdb/value.c | 10 +++++-----
gdb/value.h | 8 +++++---
6 files changed, 70 insertions(+), 18 deletions(-)
Index: gdb/ada-lang.c
===================================================================
--- gdb/ada-lang.c.orig 2008-03-31 13:34:20.000000000 -0400
+++ gdb/ada-lang.c 2008-03-31 13:34:22.000000000 -0400
@@ -2039,7 +2039,7 @@ ada_value_primitive_packed_val (struct v
v = allocate_value (type);
bytes = (unsigned char *) (valaddr + offset);
}
- else if (value_lazy (obj))
+ else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
{
v = value_at (type,
VALUE_ADDRESS (obj) + value_offset (obj) + offset);
Index: gdb/findvar.c
===================================================================
--- gdb/findvar.c.orig 2008-03-31 13:34:20.000000000 -0400
+++ gdb/findvar.c 2008-03-31 13:34:22.000000000 -0400
@@ -281,6 +281,30 @@ value_of_register (int regnum, struct fr
return reg_val;
}
+/* Return a `value' with the contents of (virtual or cooked) register
+ REGNUM as found in the specified FRAME. The register's type is
+ determined by register_type(). The value is not fetched. */
+
+struct value *
+value_of_register_lazy (struct frame_info *frame, int regnum)
+{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct value *reg_val;
+
+ gdb_assert (regnum < (gdbarch_num_regs (gdbarch)
+ + gdbarch_num_pseudo_regs (gdbarch)));
+
+ /* We should have a valid (i.e. non-sentinel) frame. */
+ gdb_assert (frame_id_p (get_frame_id (frame)));
+
+ reg_val = allocate_value (register_type (gdbarch, regnum));
+ VALUE_LVAL (reg_val) = lval_register;
+ VALUE_REGNUM (reg_val) = regnum;
+ VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
+ set_value_lazy (reg_val, 1);
+ return reg_val;
+}
+
/* Given a pointer of type TYPE in target form in BUF, return the
address it represents. */
CORE_ADDR
@@ -695,7 +719,7 @@ locate_var_value (struct symbol *var, st
if (lazy_value == 0)
error (_("Address of \"%s\" is unknown."), SYMBOL_PRINT_NAME (var));
- if (value_lazy (lazy_value)
+ if ((VALUE_LVAL (lazy_value) == lval_memory && value_lazy (lazy_value))
|| TYPE_CODE (type) == TYPE_CODE_FUNC)
{
struct value *val;
Index: gdb/valarith.c
===================================================================
--- gdb/valarith.c.orig 2008-03-31 13:34:20.000000000 -0400
+++ gdb/valarith.c 2008-03-31 13:34:22.000000000 -0400
@@ -271,7 +271,7 @@ value_subscripted_rvalue (struct value *
error (_("no such vector element"));
v = allocate_value (elt_type);
- if (value_lazy (array))
+ if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
set_value_lazy (v, 1);
else
memcpy (value_contents_writeable (v),
Index: gdb/valops.c
===================================================================
--- gdb/valops.c.orig 2008-03-31 13:34:20.000000000 -0400
+++ gdb/valops.c 2008-03-31 13:34:22.000000000 -0400
@@ -571,12 +571,38 @@ value_at_lazy (struct type *type, CORE_A
int
value_fetch_lazy (struct value *val)
{
- CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
- int length = TYPE_LENGTH (value_enclosing_type (val));
+ if (VALUE_LVAL (val) == lval_memory)
+ {
+ CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
+ int length = TYPE_LENGTH (value_enclosing_type (val));
- struct type *type = value_type (val);
- if (length)
- read_memory (addr, value_contents_all_raw (val), length);
+ struct type *type = value_type (val);
+ if (length)
+ read_memory (addr, value_contents_all_raw (val), length);
+ }
+ else if (VALUE_LVAL (val) == lval_register)
+ {
+ struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (val));
+ int regnum = VALUE_REGNUM (val);
+ struct type *type = check_typedef (value_type (val));
+
+ gdb_assert (frame != NULL);
+
+ /* Convertible register routines are used for multi-register
+ values and for interpretation in different types (e.g. float
+ or int from a double register). Lazy register values should
+ have the register's natural type, so they do not apply. */
+ gdb_assert (!gdbarch_convert_register_p (get_frame_arch (frame), regnum,
+ type));
+
+ /* Get the data. */
+ if (!get_frame_register_bytes (frame, regnum, value_offset (val),
+ TYPE_LENGTH (value_type (val)),
+ value_contents_raw (val)))
+ set_value_optimized_out (val, 1);
+ }
+ else
+ internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
set_value_lazy (val, 0);
return 0;
@@ -1424,7 +1450,7 @@ search_struct_field (char *name, struct
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
set_value_offset (v2, value_offset (arg1) + boffset);
- if (value_lazy (arg1))
+ if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
set_value_lazy (v2, 1);
else
memcpy (value_contents_raw (v2),
@@ -2852,7 +2878,7 @@ value_slice (struct value *array, int lo
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
slice = allocate_value (slice_type);
- if (value_lazy (array))
+ if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
set_value_lazy (slice, 1);
else
memcpy (value_contents_writeable (slice),
Index: gdb/value.c
===================================================================
--- gdb/value.c.orig 2008-03-31 13:34:20.000000000 -0400
+++ gdb/value.c 2008-03-31 13:34:22.000000000 -0400
@@ -137,9 +137,9 @@ struct value
short regnum;
/* If zero, contents of this value are in the contents field. If
- nonzero, contents are in inferior memory at address in the
- location.address field plus the offset field (and the lval field
- should be lval_memory).
+ nonzero, contents are in inferior. If the lval field is lval_memory,
+ the contents are in inferior memory at location.address plus offset.
+ The lval field may also be lval_register.
WARNING: This field is used by the code which handles watchpoints
(see breakpoint.c) to decide whether a particular value can be
@@ -1353,7 +1353,7 @@ value_primitive_field (struct value *arg
bases, etc. */
v = allocate_value (value_enclosing_type (arg1));
v->type = type;
- if (value_lazy (arg1))
+ if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
set_value_lazy (v, 1);
else
memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
@@ -1367,7 +1367,7 @@ value_primitive_field (struct value *arg
/* Plain old data member */
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
v = allocate_value (type);
- if (value_lazy (arg1))
+ if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
set_value_lazy (v, 1);
else
memcpy (value_contents_raw (v),
Index: gdb/value.h
===================================================================
--- gdb/value.h.orig 2008-03-31 13:34:20.000000000 -0400
+++ gdb/value.h 2008-03-31 13:34:22.000000000 -0400
@@ -135,9 +135,9 @@ extern int value_embedded_offset (struct
extern void set_value_embedded_offset (struct value *value, int val);
/* If zero, contents of this value are in the contents field. If
- nonzero, contents are in inferior memory at address in the
- location.address field plus the offset field (and the lval field
- should be lval_memory).
+ nonzero, contents are in inferior. If the lval field is lval_memory,
+ the contents are in inferior memory at location.address plus offset.
+ The lval field may also be lval_register.
WARNING: This field is used by the code which handles watchpoints
(see breakpoint.c) to decide whether a particular value can be
@@ -301,6 +301,8 @@ extern struct value *value_of_variable (
extern struct value *value_of_register (int regnum, struct frame_info *frame);
+struct value *value_of_register_lazy (struct frame_info *frame, int regnum);
+
extern int symbol_read_needs_frame (struct symbol *);
extern struct value *read_var_value (struct symbol *var,
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC 1/5] Lazy register values
2008-03-31 22:11 [RFC 1/5] Lazy register values Daniel Jacobowitz
@ 2008-04-04 19:29 ` Ulrich Weigand
2008-04-04 22:06 ` Daniel Jacobowitz
0 siblings, 1 reply; 4+ messages in thread
From: Ulrich Weigand @ 2008-04-04 19:29 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Hi Dan,
> This patch allows a register value to be lazy. Lazy register values
> are created by value_of_register_lazy and fetched by value_fetch_lazy,
> like lazy memory values. I went through every check of value_lazy and
> updated the ones which assumed this implied memory; the others guard
> calls to value_fetch_lazy, which is still correct.
I like this approach! However, I'm wondering about some of the
value_lazy changes; for example in code like:
v = allocate_value (elt_type);
if (value_lazy (array))
set_value_lazy (v, 1);
else
memcpy (value_contents_writeable (v),
value_contents (array) + elt_offs, elt_size);
if (VALUE_LVAL (array) == lval_internalvar)
VALUE_LVAL (v) = lval_internalvar_component;
else
VALUE_LVAL (v) = VALUE_LVAL (array);
VALUE_ADDRESS (v) = VALUE_ADDRESS (array);
VALUE_REGNUM (v) = VALUE_REGNUM (array);
VALUE_FRAME_ID (v) = VALUE_FRAME_ID (array);
set_value_offset (v, value_offset (array) + elt_offs);
(in value_subscripted_rvalue), it doesn't seem right to simply
change the if to
if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
If that function were ever called with a lazy register value,
the "else" part would copy from value_contents of that lazy
value, which is actually undefined.
In fact, it would appear that not changing the if at all might
be the correct solution anyway: the new value would then be
marked as lazy register value with offset.
Of course, that would then require that value_fetch_lazy
allows and handles offsets for lazy register values.
I've read through the rest of the patches in this series,
and they look fine to me. I'd be happy to convert any of
the platforms I have access to (s390, ppc, spu, ia64).
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC 1/5] Lazy register values
2008-04-04 19:29 ` Ulrich Weigand
@ 2008-04-04 22:06 ` Daniel Jacobowitz
2008-04-04 23:00 ` Ulrich Weigand
0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-04-04 22:06 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches
On Fri, Apr 04, 2008 at 09:17:38PM +0200, Ulrich Weigand wrote:
> I like this approach! However, I'm wondering about some of the
> value_lazy changes; for example in code like:
>
> v = allocate_value (elt_type);
> if (value_lazy (array))
> set_value_lazy (v, 1);
> else
> memcpy (value_contents_writeable (v),
> value_contents (array) + elt_offs, elt_size);
> (in value_subscripted_rvalue), it doesn't seem right to simply
> change the if to
> if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
>
> If that function were ever called with a lazy register value,
> the "else" part would copy from value_contents of that lazy
> value, which is actually undefined.
I don't think that's what happens - value_contents ->
value_contents_writeable -> value_fetch_lazy. I figured the fetch at
this point was acceptable; we work hard to avoid fetching memory
because it might be large, but registers are better bounded.
Do you agree, or are the offsets worthwhile after all?
> I've read through the rest of the patches in this series,
> and they look fine to me. I'd be happy to convert any of
> the platforms I have access to (s390, ppc, spu, ia64).
Thanks!
My plan is to wait until at least next week, in case anyone else
has comments; revise for comments; do as many other platforms as
I can test; and then start checking this in. I'll fix any other
platforms I'm asked to. I don't expect any substantial revisions,
in case you feel like getting a head start :-)
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC 1/5] Lazy register values
2008-04-04 22:06 ` Daniel Jacobowitz
@ 2008-04-04 23:00 ` Ulrich Weigand
0 siblings, 0 replies; 4+ messages in thread
From: Ulrich Weigand @ 2008-04-04 23:00 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
> I don't think that's what happens - value_contents ->
> value_contents_writeable -> value_fetch_lazy. I figured the fetch at
> this point was acceptable; we work hard to avoid fetching memory
> because it might be large, but registers are better bounded.
> Do you agree, or are the offsets worthwhile after all?
Ah, I see. Yes, that looks fine to me then.
> My plan is to wait until at least next week, in case anyone else
> has comments; revise for comments; do as many other platforms as
> I can test; and then start checking this in. I'll fix any other
> platforms I'm asked to. I don't expect any substantial revisions,
> in case you feel like getting a head start :-)
OK :-)
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-04-04 19:48 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-31 22:11 [RFC 1/5] Lazy register values Daniel Jacobowitz
2008-04-04 19:29 ` Ulrich Weigand
2008-04-04 22:06 ` Daniel Jacobowitz
2008-04-04 23:00 ` Ulrich Weigand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox