From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18484 invoked by alias); 22 Dec 2006 17:44:34 -0000 Received: (qmail 18457 invoked by uid 22791); 22 Dec 2006 17:44:32 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate5.de.ibm.com (HELO mtagate5.de.ibm.com) (195.212.29.154) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 22 Dec 2006 17:44:23 +0000 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate5.de.ibm.com (8.13.8/8.13.8) with ESMTP id kBMHiHhY085924 for ; Fri, 22 Dec 2006 17:44:17 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.6/8.13.6/NCO v8.1.1) with ESMTP id kBMHiHgs3158194 for ; Fri, 22 Dec 2006 18:44:17 +0100 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id kBMHiHg3016084 for ; Fri, 22 Dec 2006 18:44:17 +0100 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id kBMHiHGP016081; Fri, 22 Dec 2006 18:44:17 +0100 Message-Id: <200612221744.kBMHiHGP016081@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Fri, 22 Dec 2006 18:44:17 +0100 Subject: Re: [RFC][2/2] Rework value_from_register To: jimb@codesourcery.com (Jim Blandy) Date: Fri, 22 Dec 2006 17:44:00 -0000 From: "Ulrich Weigand" Cc: gdb-patches@sourceware.org, drow@false.org In-Reply-To: from "Jim Blandy" at Dec 15, 2006 05:17:20 PM X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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: 2006-12/txt/msg00308.txt.bz2 Hi Jim, > Hi, Ulrich. In preparation for reviewing this patch, I ran regression > tests with the [1/2] and then the [2/2] patch applied on an i686 > Fedora Core 5 system. With [2/2], GDB crashes as follows: > > /home/jimb/uberbaum/cvs-out/gdb/gdbarch.c:626: internal-error: verify_gdbarch: the following are invalid ... > value_from_register Sorry for that, I forgot to reset invalid_p to allow use of the default implementation of that callback. Please use the following version of the patch instead. Bye, Ulrich ChangeLog: * gdbarch.sh (value_from_register): New gdbarch function. * gdbarch.c, gdbarch.h: Regenerate. * findvar.c (default_value_from_register): New function. (value_from_register): Use gdbarch_value_from_register. * value.h (default_value_from_register): Declare. * spu-tdep.c (spu_convert_register_p, spu_register_to_value, spu_value_to_register): Remove. (spu_value_from_register): New function. (spu_gdbarch_init): Do not call set_gdbarch_convert_register_p, set_gdbarch_register_to_value, set_gdbarch_value_to_register. Call set_gdbarch_value_from_register. * s390-tdep.c (s390_convert_register_p, s390_register_to_value, s390_value_to_register): Remove. (s390_value_from_register): New function. (s390_gdbarch_init): Do not call set_gdbarch_convert_register_p, set_gdbarch_register_to_value, set_gdbarch_value_to_register. Call set_gdbarch_value_from_register. diff -urp gdb-orig/gdb/findvar.c gdb-head/gdb/findvar.c --- gdb-orig/gdb/findvar.c 2006-12-22 18:31:31.808803872 +0100 +++ gdb-head/gdb/findvar.c 2006-12-22 18:31:24.782673608 +0100 @@ -599,6 +599,26 @@ addresses have not been bound by the dyn return v; } +/* Install default attributes for register values. */ + +void +default_value_from_register (struct gdbarch *gdbarch, struct value *value) +{ + int len = TYPE_LENGTH (value_type (value)); + int regnum = VALUE_REGNUM (value); + + /* Any structure stored in more than one register will always be + an integral number of registers. Otherwise, you need to do + some fiddling with the last register copied here for little + endian machines. */ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG + && len < register_size (gdbarch, regnum)) + /* Big-endian, and we want less than full size. */ + set_value_offset (value, register_size (gdbarch, regnum) - len); + else + set_value_offset (value, 0); +} + /* Return a value of type TYPE, stored in register REGNUM, in frame FRAME. */ struct value * @@ -628,16 +648,8 @@ value_from_register (struct type *type, struct gdbarch *gdbarch = get_frame_arch (frame); int len = TYPE_LENGTH (type); - /* Any structure stored in more than one register will always be - an integral number of registers. Otherwise, you need to do - some fiddling with the last register copied here for little - endian machines. */ - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && len < register_size (gdbarch, regnum)) - /* Big-endian, and we want less than full size. */ - set_value_offset (v, register_size (gdbarch, regnum) - len); - else - set_value_offset (v, 0); + /* Install value attributes. */ + gdbarch_value_from_register (gdbarch, v); /* Get the data. */ if (!get_frame_register_bytes (frame, regnum, value_offset (v), len, diff -urp gdb-orig/gdb/gdbarch.c gdb-head/gdb/gdbarch.c --- gdb-orig/gdb/gdbarch.c 2006-12-08 16:49:56.000000000 +0100 +++ gdb-head/gdb/gdbarch.c 2006-12-22 18:32:24.298679992 +0100 @@ -183,6 +183,7 @@ struct gdbarch gdbarch_convert_register_p_ftype *convert_register_p; gdbarch_register_to_value_ftype *register_to_value; gdbarch_value_to_register_ftype *value_to_register; + gdbarch_value_from_register_ftype *value_from_register; gdbarch_pointer_to_address_ftype *pointer_to_address; gdbarch_address_to_pointer_ftype *address_to_pointer; gdbarch_integer_to_address_ftype *integer_to_address; @@ -309,6 +310,7 @@ struct gdbarch startup_gdbarch = 0, /* convert_register_p */ 0, /* register_to_value */ 0, /* value_to_register */ + default_value_from_register, /* value_from_register */ 0, /* pointer_to_address */ 0, /* address_to_pointer */ 0, /* integer_to_address */ @@ -429,6 +431,7 @@ gdbarch_alloc (const struct gdbarch_info current_gdbarch->cannot_fetch_register = cannot_register_not; current_gdbarch->cannot_store_register = cannot_register_not; current_gdbarch->convert_register_p = generic_convert_register_p; + current_gdbarch->value_from_register = default_value_from_register; current_gdbarch->pointer_to_address = unsigned_pointer_to_address; current_gdbarch->address_to_pointer = unsigned_address_to_pointer; current_gdbarch->return_value = legacy_return_value; @@ -562,6 +565,7 @@ verify_gdbarch (struct gdbarch *current_ /* Skip verify of cannot_store_register, invalid_p == 0 */ /* Skip verify of get_longjmp_target, has predicate */ /* Skip verify of convert_register_p, invalid_p == 0 */ + /* Skip verify of value_from_register, invalid_p == 0 */ /* Skip verify of pointer_to_address, invalid_p == 0 */ /* Skip verify of address_to_pointer, invalid_p == 0 */ /* Skip verify of integer_to_address, has predicate */ @@ -1586,6 +1590,9 @@ gdbarch_dump (struct gdbarch *current_gd fprintf_unfiltered (file, "gdbarch_dump: unwind_sp = <0x%lx>\n", (long) current_gdbarch->unwind_sp); + fprintf_unfiltered (file, + "gdbarch_dump: value_from_register = <0x%lx>\n", + (long) current_gdbarch->value_from_register); #ifdef VALUE_TO_REGISTER fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", @@ -2636,6 +2643,23 @@ set_gdbarch_value_to_register (struct gd gdbarch->value_to_register = value_to_register; } +void +gdbarch_value_from_register (struct gdbarch *gdbarch, struct value *value) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->value_from_register != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_value_from_register called\n"); + gdbarch->value_from_register (gdbarch, value); +} + +void +set_gdbarch_value_from_register (struct gdbarch *gdbarch, + gdbarch_value_from_register_ftype value_from_register) +{ + gdbarch->value_from_register = value_from_register; +} + CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf) { diff -urp gdb-orig/gdb/gdbarch.h gdb-head/gdb/gdbarch.h --- gdb-orig/gdb/gdbarch.h 2006-12-08 16:49:56.000000000 +0100 +++ gdb-head/gdb/gdbarch.h 2006-12-22 18:31:24.839797944 +0100 @@ -704,6 +704,10 @@ extern void set_gdbarch_value_to_registe #define VALUE_TO_REGISTER(frame, regnum, type, buf) (gdbarch_value_to_register (current_gdbarch, frame, regnum, type, buf)) #endif +typedef void (gdbarch_value_from_register_ftype) (struct gdbarch *gdbarch, struct value *value); +extern void gdbarch_value_from_register (struct gdbarch *gdbarch, struct value *value); +extern void set_gdbarch_value_from_register (struct gdbarch *gdbarch, gdbarch_value_from_register_ftype *value_from_register); + typedef CORE_ADDR (gdbarch_pointer_to_address_ftype) (struct type *type, const gdb_byte *buf); extern CORE_ADDR gdbarch_pointer_to_address (struct gdbarch *gdbarch, struct type *type, const gdb_byte *buf); extern void set_gdbarch_pointer_to_address (struct gdbarch *gdbarch, gdbarch_pointer_to_address_ftype *pointer_to_address); diff -urp gdb-orig/gdb/gdbarch.sh gdb-head/gdb/gdbarch.sh --- gdb-orig/gdb/gdbarch.sh 2006-12-08 16:49:56.000000000 +0100 +++ gdb-head/gdb/gdbarch.sh 2006-12-22 18:31:58.273775144 +0100 @@ -496,6 +496,7 @@ v:=:int:believe_pcc_promotion::::::: f:=:int:convert_register_p:int regnum, struct type *type:regnum, type:0:generic_convert_register_p::0 f:=:void:register_to_value:struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf:frame, regnum, type, buf:0 f:=:void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf:frame, regnum, type, buf:0 +m::void:value_from_register:struct value *value:value::default_value_from_register::0 # f:=:CORE_ADDR:pointer_to_address:struct type *type, const gdb_byte *buf:type, buf::unsigned_pointer_to_address::0 f:=:void:address_to_pointer:struct type *type, gdb_byte *buf, CORE_ADDR addr:type, buf, addr::unsigned_address_to_pointer::0 diff -urp gdb-orig/gdb/s390-tdep.c gdb-head/gdb/s390-tdep.c --- gdb-orig/gdb/s390-tdep.c 2006-12-08 16:49:56.000000000 +0100 +++ gdb-head/gdb/s390-tdep.c 2006-12-22 18:31:24.935783352 +0100 @@ -306,36 +306,16 @@ s390x_pseudo_register_write (struct gdba /* 'float' values are stored in the upper half of floating-point registers, even though we are otherwise a big-endian platform. */ -static int -s390_convert_register_p (int regno, struct type *type) -{ - return (regno >= S390_F0_REGNUM && regno <= S390_F15_REGNUM) - && TYPE_LENGTH (type) < 8; -} - static void -s390_register_to_value (struct frame_info *frame, int regnum, - struct type *valtype, gdb_byte *out) +s390_value_from_register (struct gdbarch *gdbarch, struct value *value) { - gdb_byte in[8]; - int len = TYPE_LENGTH (valtype); - gdb_assert (len < 8); + int len = TYPE_LENGTH (value_type (value)); + int regnum = VALUE_REGNUM (value); - get_frame_register (frame, regnum, in); - memcpy (out, in, len); -} + default_value_from_register (gdbarch, value); -static void -s390_value_to_register (struct frame_info *frame, int regnum, - struct type *valtype, const gdb_byte *in) -{ - gdb_byte out[8]; - int len = TYPE_LENGTH (valtype); - gdb_assert (len < 8); - - memset (out, 0, 8); - memcpy (out, in, len); - put_frame_register (frame, regnum, out); + if (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM && len < 8) + set_value_offset (value, 0); } /* Register groups. */ @@ -2411,9 +2391,7 @@ s390_gdbarch_init (struct gdbarch_info i set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); set_gdbarch_dwarf_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum); - set_gdbarch_convert_register_p (gdbarch, s390_convert_register_p); - set_gdbarch_register_to_value (gdbarch, s390_register_to_value); - set_gdbarch_value_to_register (gdbarch, s390_value_to_register); + set_gdbarch_value_from_register (gdbarch, s390_value_from_register); set_gdbarch_register_reggroup_p (gdbarch, s390_register_reggroup_p); set_gdbarch_regset_from_core_section (gdbarch, s390_regset_from_core_section); diff -urp gdb-orig/gdb/spu-tdep.c gdb-head/gdb/spu-tdep.c --- gdb-orig/gdb/spu-tdep.c 2006-12-13 15:09:07.000000000 +0100 +++ gdb-head/gdb/spu-tdep.c 2006-12-22 18:31:24.949781224 +0100 @@ -145,37 +145,19 @@ spu_pseudo_register_write (struct gdbarc /* Value conversion -- access scalar values at the preferred slot. */ -static int -spu_convert_register_p (int regno, struct type *type) -{ - return regno < SPU_NUM_GPRS && TYPE_LENGTH (type) < 16; -} - static void -spu_register_to_value (struct frame_info *frame, int regnum, - struct type *valtype, gdb_byte *out) +spu_value_from_register (struct gdbarch *gdbarch, struct value *value) { - gdb_byte in[16]; - int len = TYPE_LENGTH (valtype); - int preferred_slot = len < 4 ? 4 - len : 0; - gdb_assert (len < 16); + int len = TYPE_LENGTH (value_type (value)); + int regnum = VALUE_REGNUM (value); - get_frame_register (frame, regnum, in); - memcpy (out, in + preferred_slot, len); -} + default_value_from_register (gdbarch, value); -static void -spu_value_to_register (struct frame_info *frame, int regnum, - struct type *valtype, const gdb_byte *in) -{ - gdb_byte out[16]; - int len = TYPE_LENGTH (valtype); - int preferred_slot = len < 4 ? 4 - len : 0; - gdb_assert (len < 16); - - memset (out, 0, 16); - memcpy (out + preferred_slot, in, len); - put_frame_register (frame, regnum, out); + if (regnum < SPU_NUM_GPRS && len < 16) + { + int preferred_slot = len < 4 ? 4 - len : 0; + set_value_offset (value, preferred_slot); + } } /* Register groups. */ @@ -1050,9 +1032,7 @@ spu_gdbarch_init (struct gdbarch_info in set_gdbarch_register_type (gdbarch, spu_register_type); set_gdbarch_pseudo_register_read (gdbarch, spu_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, spu_pseudo_register_write); - set_gdbarch_convert_register_p (gdbarch, spu_convert_register_p); - set_gdbarch_register_to_value (gdbarch, spu_register_to_value); - set_gdbarch_value_to_register (gdbarch, spu_value_to_register); + set_gdbarch_value_from_register (gdbarch, spu_value_from_register); set_gdbarch_register_reggroup_p (gdbarch, spu_register_reggroup_p); /* Data types. */ diff -urp gdb-orig/gdb/value.h gdb-head/gdb/value.h --- gdb-orig/gdb/value.h 2006-12-08 16:49:56.000000000 +0100 +++ gdb-head/gdb/value.h 2006-12-22 18:31:24.953780616 +0100 @@ -279,6 +279,9 @@ extern struct value *value_from_string ( extern struct value *value_at (struct type *type, CORE_ADDR addr); extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr); +extern void default_value_from_register (struct gdbarch *gdbarch, + struct value *value); + extern struct value *value_from_register (struct type *type, int regnum, struct frame_info *frame); -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com