From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Subject: Re: [0/2] Inspect extra signal information
Date: Mon, 12 Jan 2009 18:49:00 -0000 [thread overview]
Message-ID: <200901121848.49148.pedro@codesourcery.com> (raw)
In-Reply-To: <200901121846.51709.pedro@codesourcery.com>
[-- Attachment #1: Type: text/plain, Size: 591 bytes --]
On Monday 12 January 2009 18:46:51, Pedro Alves wrote:
>
> part 1:
>
> - Adds some infrastracture to be able to register reader and writer
> functions that are responsible for reading and writing
> a ``struct value'''s value. We called those lval_computed values. We've
> been using these kinds of values for other things in our tree for a
> couple of years already --- I've piggy-backed on that, so I got to
> push it. :-)
>
> This first patch applies on top of this other one:
>
> http://sourceware.org/ml/gdb-patches/2009-01/msg00252.html
>
--
Pedro Alves
[-- Attachment #2: lval_computed.diff --]
[-- Type: text/x-diff, Size: 9719 bytes --]
2009-01-12 Jim Blandy <jimb@codesourcery.com>
Daniel Jacobowitz <dan@codesourcery.com>
Vladimir Prus <vladimir@codesourcery.com>
Pedro Alves <pedro@codesourcery.com>
* defs.h (enum lval_type): New value: lval_computed.
* value.h (struct lval_funcs): New type.
(allocate_computed_value, value_computed_funcs)
(value_computed_closure): New declarations.
* value.c (struct value): Add a structure to the location union
for computed lvalues, containing 'funcs' and 'closure' members.
(allocate_computed_value, value_computed_funcs)
(value_computed_closure): New functions.
(value_free): For computed lvalues, call the closure's
'free_closure' function before freeing the value itself.
(value_copy): If we're copying an lval_computed value, call the
closure's 'copy_closure' function.
(set_value_component_location): If the original value is a
computed lvalue, then call the closure's 'copy_closure' function.
(value_of_internalvar): If an internal variable's value is a
computed lvalue, make retrieving its value produce an equivalent
computed lvalue.
* valops.c (value_fetch_lazy): Unlazy computed lvalues by calling
their read function.
(value_assign): Assign to computed lvalues by calling their write
function.
---
gdb/defs.h | 5 ++-
gdb/valops.c | 12 +++++++-
gdb/value.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
gdb/value.h | 54 +++++++++++++++++++++++++++++++++++++
4 files changed, 151 insertions(+), 5 deletions(-)
Index: gdb/defs.h
===================================================================
--- gdb/defs.h.orig 2009-01-11 15:40:11.000000000 +0000
+++ gdb/defs.h 2009-01-12 16:29:28.000000000 +0000
@@ -652,7 +652,10 @@ enum lval_type
/* In a gdb internal variable. */
lval_internalvar,
/* Part of a gdb internal variable (structure field). */
- lval_internalvar_component
+ lval_internalvar_component,
+ /* Value's bits are fetched and stored using functions provided by
+ its creator. */
+ lval_computed
};
/* Control types for commands */
Index: gdb/value.h
===================================================================
--- gdb/value.h.orig 2009-01-12 12:40:32.000000000 +0000
+++ gdb/value.h 2009-01-12 16:48:53.000000000 +0000
@@ -142,6 +142,60 @@ extern void set_value_pointed_to_offset
extern int value_embedded_offset (struct value *value);
extern void set_value_embedded_offset (struct value *value, int val);
+/* For lval_computed values, this structure holds functions used to
+ retrieve and set the value (or portions of the value).
+
+ For each function, 'V' is the 'this' pointer: an lval_funcs
+ function F may always assume that the V it receives is an
+ lval_computed value, and has F in the appropriate slot of its
+ lval_funcs structure. */
+
+struct lval_funcs
+{
+ /* Fill in VALUE's contents. This is used to "un-lazy" values. If
+ a problem arises in obtaining VALUE's bits, this function should
+ call 'error'. */
+ void (*read) (struct value *v);
+
+ /* Handle an assignment TOVAL = FROMVAL by writing the value of
+ FROMVAL to TOVAL's location. The contents of TOVAL have not yet
+ been updated. If a problem arises in doing so, this function
+ should call 'error'. */
+ void (*write) (struct value *toval, struct value *fromval);
+
+ /* Return a duplicate of VALUE's closure, for use in a new value.
+ This may simply return the same closure, if VALUE's is
+ reference-counted or statically allocated.
+
+ This may be NULL, in which case VALUE's closure is re-used in the
+ new value. */
+ void *(*copy_closure) (struct value *v);
+
+ /* Drop VALUE's reference to its closure. Maybe this frees the
+ closure; maybe this decrements a reference count; maybe the
+ closure is statically allocated and this does nothing.
+
+ This may be NULL, in which case no action is taken to free
+ VALUE's closure. */
+ void (*free_closure) (struct value *v);
+};
+
+/* Create a computed lvalue, with type TYPE, function pointers FUNCS,
+ and closure CLOSURE. */
+
+extern struct value *allocate_computed_value (struct type *type,
+ struct lval_funcs *funcs,
+ void *closure);
+
+/* If VALUE is lval_computed, return its lval_funcs structure. */
+
+extern struct lval_funcs *value_computed_funcs (struct value *value);
+
+/* If VALUE is lval_computed, return its closure. The meaning of the
+ returned value depends on the functions VALUE uses. */
+
+extern void *value_computed_closure (struct value *value);
+
/* If zero, contents of this value are in the contents field. If
nonzero, contents are in inferior. If the lval field is lval_memory,
the contents are in inferior memory at location.address plus offset.
Index: gdb/value.c
===================================================================
--- gdb/value.c.orig 2009-01-12 11:25:23.000000000 +0000
+++ gdb/value.c 2009-01-12 16:48:54.000000000 +0000
@@ -63,6 +63,15 @@ struct value
/* Pointer to internal variable. */
struct internalvar *internalvar;
+
+ /* If lval == lval_computed, this is a set of function pointers
+ to use to access and describe the value, and a closure pointer
+ for them to use. */
+ struct
+ {
+ struct lval_funcs *funcs; /* Functions to call. */
+ void *closure; /* Closure for those functions to use. */
+ } computed;
} location;
/* Describes offset of a value within lval of a structure in bytes.
@@ -296,6 +305,20 @@ value_remove_from_list (struct value **h
}
}
+struct value *
+allocate_computed_value (struct type *type,
+ struct lval_funcs *funcs,
+ void *closure)
+{
+ struct value *v = allocate_value (type);
+ VALUE_LVAL (v) = lval_computed;
+ v->location.computed.funcs = funcs;
+ v->location.computed.closure = closure;
+ set_value_lazy (v, 1);
+
+ return v;
+}
+
/* Accessor methods. */
struct value *
@@ -458,6 +481,22 @@ set_value_pointed_to_offset (struct valu
value->pointed_to_offset = val;
}
+struct lval_funcs *
+value_computed_funcs (struct value *v)
+{
+ gdb_assert (VALUE_LVAL (v) == lval_computed);
+
+ return v->location.computed.funcs;
+}
+
+void *
+value_computed_closure (struct value *v)
+{
+ gdb_assert (VALUE_LVAL (v) == lval_computed);
+
+ return v->location.computed.closure;
+}
+
enum lval_type *
deprecated_value_lval_hack (struct value *value)
{
@@ -512,7 +551,17 @@ void
value_free (struct value *val)
{
if (val)
- xfree (val->contents);
+ {
+ if (VALUE_LVAL (val) == lval_computed)
+ {
+ struct lval_funcs *funcs = val->location.computed.funcs;
+
+ if (funcs->free_closure)
+ funcs->free_closure (val);
+ }
+
+ xfree (val->contents);
+ }
xfree (val);
}
@@ -625,6 +674,13 @@ value_copy (struct value *arg)
TYPE_LENGTH (value_enclosing_type (arg)));
}
+ if (VALUE_LVAL (val) == lval_computed)
+ {
+ struct lval_funcs *funcs = val->location.computed.funcs;
+
+ if (funcs->copy_closure)
+ val->location.computed.closure = funcs->copy_closure (val);
+ }
return val;
}
@@ -635,7 +691,15 @@ set_value_component_location (struct val
VALUE_LVAL (component) = lval_internalvar_component;
else
VALUE_LVAL (component) = VALUE_LVAL (whole);
+
component->location = whole->location;
+ if (VALUE_LVAL (whole) == lval_computed)
+ {
+ struct lval_funcs *funcs = whole->location.computed.funcs;
+
+ if (funcs->copy_closure)
+ component->location.computed.closure = funcs->copy_closure (whole);
+ }
}
\f
@@ -872,8 +936,23 @@ value_of_internalvar (struct internalvar
val = value_copy (var->value);
if (value_lazy (val))
value_fetch_lazy (val);
- VALUE_LVAL (val) = lval_internalvar;
- VALUE_INTERNALVAR (val) = var;
+
+ /* If the variable's value is a computed lvalue, we want references
+ to it to produce another computed lvalue, where referencces and
+ assignments actually operate through the computed value's
+ functions.
+
+ This means that internal variables with computed values behave a
+ little differently from other internal variables: assignments to
+ them don't just replace the previous value altogether. At the
+ moment, this seems like the behavior we want. */
+ if (var->value->lval == lval_computed)
+ VALUE_LVAL (val) = lval_computed;
+ else
+ {
+ VALUE_LVAL (val) = lval_internalvar;
+ VALUE_INTERNALVAR (val) = var;
+ }
/* Values are always stored in the target's byte order. When connected to a
target this will most likely always be correct, so there's normally no
Index: gdb/valops.c
===================================================================
--- gdb/valops.c.orig 2009-01-12 11:25:23.000000000 +0000
+++ gdb/valops.c 2009-01-12 14:21:01.000000000 +0000
@@ -727,6 +727,8 @@ value_fetch_lazy (struct value *val)
watchpoints from trying to watch the saved frame pointer. */
value_free_to_mark (mark);
}
+ else if (VALUE_LVAL (val) == lval_computed)
+ value_computed_funcs (val)->read (val);
else
internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
@@ -895,7 +897,15 @@ value_assign (struct value *toval, struc
observer_notify_target_changed (¤t_target);
break;
}
-
+
+ case lval_computed:
+ {
+ struct lval_funcs *funcs = value_computed_funcs (toval);
+
+ funcs->write (toval, fromval);
+ }
+ break;
+
default:
error (_("Left operand of assignment is not an lvalue."));
}
next prev parent reply other threads:[~2009-01-12 18:49 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-12 18:47 Pedro Alves
2009-01-12 18:49 ` Pedro Alves [this message]
2009-01-12 18:52 ` [1/2] " Pedro Alves
2009-01-12 19:40 ` Eli Zaretskii
2009-02-02 16:51 ` Pedro Alves
2009-02-02 21:04 ` Eli Zaretskii
2009-02-05 1:14 ` Pedro Alves
2009-02-05 20:30 ` Eli Zaretskii
2009-02-06 23:31 ` Pedro Alves
2009-01-12 18:50 ` [2/2] " Pedro Alves
2009-01-12 19:39 ` Eli Zaretskii
2009-01-13 12:32 ` Pedro Alves
2009-01-13 18:55 ` Eli Zaretskii
2009-01-13 19:08 ` Pedro Alves
2009-01-13 19:15 ` Eli Zaretskii
2009-02-06 23:35 ` Pedro Alves
2009-02-09 6:23 ` Paul Pluzhnikov
2009-02-09 22:17 ` Pedro Alves
2009-04-06 19:00 ` Paul Pluzhnikov
2009-04-06 19:18 ` relying on testsuite results Thiago Jung Bauermann
2009-04-06 19:33 ` Paul Pluzhnikov
2009-04-06 19:57 ` Daniel Jacobowitz
2009-04-06 19:51 ` Tom Tromey
2009-04-06 20:22 ` Mark Kettenis
2009-04-07 14:57 ` [2/2] Inspect extra signal information Pedro Alves
2009-01-12 23:27 ` [0/2] " Mark Kettenis
2009-01-13 11:05 ` Pedro Alves
2009-01-13 18:42 ` Eli Zaretskii
2009-01-13 18:50 ` Pedro Alves
2009-01-13 19:19 ` Eli Zaretskii
2009-01-13 19:37 ` Pedro Alves
2009-01-13 19:47 ` Pedro Alves
2009-02-02 14:40 ` Pedro Alves
2009-02-02 20:49 ` Mark Kettenis
2009-02-03 15:02 ` Pedro Alves
2009-02-03 16:42 ` Ulrich Weigand
2009-02-03 18:06 ` Daniel Jacobowitz
2009-02-03 18:24 ` Pedro Alves
2009-02-03 19:04 ` Daniel Jacobowitz
2009-02-03 19:51 ` Pedro Alves
2009-02-03 23:18 ` Doug Evans
2009-02-03 23:50 ` Pedro Alves
2009-02-04 0:17 ` Doug Evans
2009-02-04 0:24 ` Daniel Jacobowitz
2009-02-04 0:49 ` Pedro Alves
2009-02-04 21:02 ` [3/2] Inspect extra signal information, handle amd64 bi-arch gdb Pedro Alves
2009-02-04 21:17 ` Daniel Jacobowitz
2009-02-06 23:37 ` Pedro Alves
2009-02-07 2:28 ` Paul Pluzhnikov
2009-02-07 14:56 ` Pedro Alves
2009-02-07 16:14 ` Paul Pluzhnikov
2009-02-04 22:07 ` Doug Evans
2009-02-03 18:23 ` [0/2] Inspect extra signal information Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200901121848.49148.pedro@codesourcery.com \
--to=pedro@codesourcery.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox