From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31909 invoked by alias); 26 Oct 2011 21:44:21 -0000 Received: (qmail 31898 invoked by uid 22791); 26 Oct 2011 21:44:19 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,TW_CP X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 26 Oct 2011 21:44:04 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id E2A8C2BB4CF; Wed, 26 Oct 2011 17:44:03 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id sfOpCrmo08y3; Wed, 26 Oct 2011 17:44:03 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 913642BB3B0; Wed, 26 Oct 2011 17:44:03 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id CF170145615; Wed, 26 Oct 2011 17:44:00 -0400 (EDT) Date: Wed, 26 Oct 2011 22:11:00 -0000 From: Joel Brobecker To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: [RFA/RFC] Restore old handling of multi-register variables Message-ID: <20111026214400.GW19246@adacore.com> References: <1317675787-7351-1-git-send-email-brobecker@adacore.com> <201110252002.38708.pedro@codesourcery.com> <20111025203022.GQ19246@adacore.com> <201110252149.34078.pedro@codesourcery.com> <20111026213726.GV19246@adacore.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="oPmsXEqKQNHCSXW7" Content-Disposition: inline In-Reply-To: <20111026213726.GV19246@adacore.com> User-Agent: Mutt/1.5.20 (2009-06-14) 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: 2011-10/txt/msg00711.txt.bz2 --oPmsXEqKQNHCSXW7 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1170 > I have also started looking at converting the register_to_value > gdbarch method to using values instead of buffer and a couple of > parameters. Not very difficult, but not trivial either. That makes > me worried about introducing bugs during the conversion, and > I won't be able to test most configurations. > > I'll send a patch as a follow-up email to this one. It's not complete, > but gives us an idea, and we can decide whether we want to continue > or not (FYI: I will have very little time for this within the next > couple of weeks). So, here is the patch. I only did the conversion for alpha and i386/i387. It shows the benefits, but it also reveals that the implementation can be a little awkward, because the support routines that are used of course where implemented using buffers rather than values. And in the end, the transformations need to be performed on the contents of those buffers, so in their context, it might even make some kind of sense. Overall, this still seems like a step in the right direction, but I am definitely concerned about introducing bugs on platforms that I cannot test... So, what do you think we should do? -- Joel --oPmsXEqKQNHCSXW7 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="wip-register_to_value.diff" Content-length: 10874 commit 50bc176d304fef14f4823670e5ce6075c64419d7 Author: Joel Brobecker Date: Wed Oct 26 11:11:56 2011 -0700 WIP (gdbarch_register_to_value) diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index b6b9cf8..e67bdec 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -492,7 +492,7 @@ F:int:get_longjmp_target:struct frame_info *frame, CORE_ADDR *pc:frame, pc v:int:believe_pcc_promotion::::::: # m:int:convert_register_p:int regnum, struct type *type:regnum, type:0:generic_convert_register_p::0 -f:int:register_to_value:struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep:frame, regnum, type, buf, optimizedp, unavailablep:0 +f:struct value *:register_to_value:struct frame_info *frame, int regnum, struct type *type:frame, regnum, type:0 f:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf:frame, regnum, type, buf:0 # Construct a value representing the contents of register REGNUM in # frame FRAME, interpreted as type TYPE. The routine needs to diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 7fedca7..975377f 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -402,8 +402,8 @@ typedef int (gdbarch_convert_register_p_ftype) (struct gdbarch *gdbarch, int reg 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); -typedef int (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep); -extern int gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep); +typedef struct value * (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type); +extern struct value * gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type); extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value); typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index db4d882..cfa55b0 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -2339,14 +2339,14 @@ set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch->convert_register_p = convert_register_p; } -int -gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep) +struct value * +gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->register_to_value != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_register_to_value called\n"); - return gdbarch->register_to_value (frame, regnum, type, buf, optimizedp, unavailablep); + return gdbarch->register_to_value (frame, regnum, type); } void diff --git a/gdb/findvar.c b/gdb/findvar.c index 54e7b4a..5b8e679 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -663,8 +663,6 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) if (gdbarch_convert_register_p (gdbarch, regnum, type1)) { - int optim, unavail, ok; - /* 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 @@ -672,21 +670,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame) the corresponding [integer] type (see Alpha). The assumption is that gdbarch_register_to_value populates the entire value including the location. */ - v = allocate_value (type); - VALUE_LVAL (v) = lval_register; - VALUE_FRAME_ID (v) = get_frame_id (frame); - VALUE_REGNUM (v) = regnum; - ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1, - value_contents_raw (v), &optim, - &unavail); - - if (!ok) - { - if (optim) - set_value_optimized_out (v, 1); - if (unavail) - mark_value_bytes_unavailable (v, 0, TYPE_LENGTH (type)); - } + v = gdbarch_register_to_value (gdbarch, frame, regnum, type1); } else { diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 2e4bb6f..3913ca7 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -211,7 +211,10 @@ alpha_lds (struct gdbarch *gdbarch, void *out, const void *in) } /* Similarly, this represents exactly the conversion performed by - the STS instruction. */ + the STS instruction. + + Note: IN and OUT can be equal, in which case the buffer contents + will simply be replaced by the value after conversion. */ static void alpha_sts (struct gdbarch *gdbarch, void *out, const void *in) @@ -238,25 +241,23 @@ alpha_convert_register_p (struct gdbarch *gdbarch, int regno, && TYPE_LENGTH (type) != 8); } -static int +static struct value * alpha_register_to_value (struct frame_info *frame, int regnum, - struct type *valtype, gdb_byte *out, - int *optimizedp, int *unavailablep) + struct type *valtype) { struct gdbarch *gdbarch = get_frame_arch (frame); - gdb_byte in[MAX_REGISTER_SIZE]; + struct value *value; - /* Convert to TYPE. */ - if (!get_frame_register_bytes (frame, regnum, 0, - register_size (gdbarch, regnum), - in, optimizedp, unavailablep)) - return 0; + value = gdbarch_value_from_register (gdbarch, valtype, regnum, frame); + read_frame_register_value (value, frame); + if (value_optimized_out (value) || !value_entirely_available (value)) + return value; if (TYPE_LENGTH (valtype) == 4) { - alpha_sts (gdbarch, out, in); - *optimizedp = *unavailablep = 0; - return 1; + gdb_byte *contents = value_contents_writeable (value); + alpha_sts (gdbarch, contents, contents); + return value; } error (_("Cannot retrieve value from floating point register")); diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index a381a51..eedcb29 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -3106,39 +3106,20 @@ i386_convert_register_p (struct gdbarch *gdbarch, /* Read a value of type TYPE from register REGNUM in frame FRAME, and return its contents in TO. */ -static int +static struct value * i386_register_to_value (struct frame_info *frame, int regnum, - struct type *type, gdb_byte *to, - int *optimizedp, int *unavailablep) + struct type *type) { struct gdbarch *gdbarch = get_frame_arch (frame); - int len = TYPE_LENGTH (type); + struct value *value; if (i386_fp_regnum_p (gdbarch, regnum)) - return i387_register_to_value (frame, regnum, type, to, - optimizedp, unavailablep); - - /* Read a value spread across multiple registers. */ - - gdb_assert (len > 4 && len % 4 == 0); - - while (len > 0) - { - gdb_assert (regnum != -1); - gdb_assert (register_size (gdbarch, regnum) == 4); - - if (!get_frame_register_bytes (frame, regnum, 0, - register_size (gdbarch, regnum), - to, optimizedp, unavailablep)) - return 0; + return i387_register_to_value (frame, regnum, type); - regnum = i386_next_regnum (regnum); - len -= 4; - to += 4; - } - - *optimizedp = *unavailablep = 0; - return 1; + value = gdbarch_value_from_register (gdbarch, type, regnum, frame); + read_frame_register_value (value, frame); + + return value; } /* Write the contents FROM of a value of type TYPE into register diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c index c4ace82..e505421 100644 --- a/gdb/i387-tdep.c +++ b/gdb/i387-tdep.c @@ -307,12 +307,12 @@ i387_convert_register_p (struct gdbarch *gdbarch, int regnum, /* Read a value of type TYPE from register REGNUM in frame FRAME, and return its contents in TO. */ -int +struct value * i387_register_to_value (struct frame_info *frame, int regnum, - struct type *type, gdb_byte *to, - int *optimizedp, int *unavailablep) + struct type *type) { struct gdbarch *gdbarch = get_frame_arch (frame); + struct value *value; gdb_byte from[I386_MAX_REGISTER_SIZE]; gdb_assert (i386_fp_regnum_p (gdbarch, regnum)); @@ -321,19 +321,24 @@ i387_register_to_value (struct frame_info *frame, int regnum, if (TYPE_CODE (type) != TYPE_CODE_FLT) { warning (_("Cannot convert floating-point register value " - "to non-floating-point type.")); - *optimizedp = *unavailablep = 0; - return 0; + "to non-floating-point type.")); + value = allocate_value (type); + mark_value_bytes_unavailable (value, 0, + TYPE_LENGTH (check_typedef (type))); + + return value; } /* Convert to TYPE. */ - if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type), - from, optimizedp, unavailablep)) - return 0; - - convert_typed_floating (from, i387_ext_type (gdbarch), to, type); - *optimizedp = *unavailablep = 0; - return 1; + value = gdbarch_value_from_register (gdbarch, type, regnum, frame); + read_frame_register_value (value, frame); + if (value_optimized_out (value) || !value_entirely_available (value)) + return value; + + memcpy (from, value_contents (value), TYPE_LENGTH (check_typedef (type))); + convert_typed_floating (from, i387_ext_type (gdbarch), + value_contents_writeable (value), type); + return value; } /* Write the contents FROM of a value of type TYPE into register diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h index b876549..d317a25 100644 --- a/gdb/i387-tdep.h +++ b/gdb/i387-tdep.h @@ -26,6 +26,7 @@ struct frame_info; struct regcache; struct type; struct ui_file; +struct value; /* Number of i387 floating point registers. */ #define I387_NUM_REGS 16 @@ -63,12 +64,10 @@ extern void i387_print_float_info (struct gdbarch *gdbarch, extern int i387_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type); -/* Read a value of type TYPE from register REGNUM in frame FRAME, and - return its contents in TO. */ +/* Return a value of type TYPE from register REGNUM in frame FRAME. */ -extern int i387_register_to_value (struct frame_info *frame, int regnum, - struct type *type, gdb_byte *to, - int *optimizedp, int *unavailablep); +extern struct value *i387_register_to_value (struct frame_info *frame, + int regnum, struct type *type); /* Write the contents FROM of a value of type TYPE into register REGNUM in frame FRAME. */ --oPmsXEqKQNHCSXW7--