From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20581 invoked by alias); 31 Mar 2008 22:07:22 -0000 Received: (qmail 20450 invoked by uid 22791); 31 Mar 2008 22:07:19 -0000 X-Spam-Check-By: sourceware.org Received: from NaN.false.org (HELO nan.false.org) (208.75.86.248) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 31 Mar 2008 22:06:59 +0000 Received: from nan.false.org (localhost [127.0.0.1]) by nan.false.org (Postfix) with ESMTP id A32CA983BE for ; Mon, 31 Mar 2008 22:06:57 +0000 (GMT) Received: from caradoc.them.org (22.svnf5.xdsl.nauticom.net [209.195.183.55]) by nan.false.org (Postfix) with ESMTP id 6B17F9802B for ; Mon, 31 Mar 2008 22:06:57 +0000 (GMT) Received: from drow by caradoc.them.org with local (Exim 4.69) (envelope-from ) id 1JgS9Y-0005oB-Qd for gdb-patches@sourceware.org; Mon, 31 Mar 2008 18:06:56 -0400 Date: Mon, 31 Mar 2008 22:11:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org Subject: [RFC 1/5] Lazy register values Message-ID: <20080331220656.GA22012@caradoc.them.org> Mail-Followup-To: gdb-patches@sourceware.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.17 (2007-12-11) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-03/txt/msg00511.txt.bz2 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 * 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,