From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26600 invoked by alias); 17 Feb 2003 16:54:44 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 26593 invoked from network); 17 Feb 2003 16:54:43 -0000 Received: from unknown (HELO cerbere.u-strasbg.fr) (130.79.112.250) by 172.16.49.205 with SMTP; 17 Feb 2003 16:54:43 -0000 Received: from laocoon.ics.u-strasbg.fr (laocoon.u-strasbg.fr [130.79.112.72]) by cerbere.u-strasbg.fr (Postfix) with ESMTP id 569012C26E5 for ; Mon, 17 Feb 2003 17:56:37 +0100 (CET) Message-Id: <5.0.2.1.2.20030217174903.02c193e8@ics.u-strasbg.fr> X-Sender: muller@ics.u-strasbg.fr Date: Mon, 17 Feb 2003 16:54:00 -0000 To: gdb-patches@sources.redhat.com From: Pierre Muller Subject: [RFC] Support alternate 'long double' size. Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_358882075==_" X-SW-Source: 2003-02/txt/msg00350.txt.bz2 --=====================_358882075==_ Content-Type: text/plain; charset="us-ascii" Content-length: 1995 The i387 floting point unit handles 'long double' float type with 80 bits, but GCC and most compilers pretend that this type is 96 bit long (mainly for alignment purposes). Nevertheless, at least Free Pascal does use 80 bit size for this type. As GDB does not recognize this size, the stabs output has been twisted to simulate 96 bit 'long double' type, so that normal 'extended' (the Free Pascal name of this float type) variables can be inspected correctly. Nevertheless, this leads to a very bad situation when we try to inspect Free Pascal arrays of extended, because GDB searches the second element at offset 12 (in bytes) relative to the first address, when it is in fact at offset 10. To avoid GDB from outputing non-sense, I added an explicit size specific to the stabs output, this leads CVS head GDB to claim about the fact that it does not know how to handle 10 byte long floats. The following patch add a new variable to the gdbarch vector: long_double_bit_alternate which can be used to accept a second size for the same type 'long double'. The default value is 0, which renders it useless unless explicitly set. It is then set to 80 bit in i386-tdep.c The addition of long_double_bit_alternate variable leads to the creation of the new macro TARGET_LONG_DOUBLE_BIT_ALTERNATE that is used in function floatformat_from_length to return the same type as for TARGET_LONG_DOUBLE_BIT. This simple patch allows to correctly display arrays of extended in Free Pascal compiled code. I don't know really if this is used in other compilers, but I suspect that it could be also used in x86-64-tdep.c or ia64-tdep.c. ChangeLog entry: 2003-02-17 Pierre Muller * gdbarch.sh: Add long_double_bit_alternate variable. * gdbarch.h, gdbarch.c: Re-genarate. * doublest.c (floatformat_from_length): Accept also long_double_bit_alternate length for 'long double' type. * i386-tdep.c (i386_gdbarch_init ): Set long_double_bit_alternate to 80. --=====================_358882075==_ Content-Type: text/plain; charset="us-ascii" Content-length: 6915 Index: gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.181 diff -u -p -r1.181 gdbarch.c --- gdbarch.c 29 Jan 2003 18:07:06 -0000 1.181 +++ gdbarch.c 17 Feb 2003 16:07:19 -0000 @@ -140,6 +140,7 @@ struct gdbarch int float_bit; int double_bit; int long_double_bit; + int long_double_bit_alternate; int ptr_bit; int addr_bit; int bfd_vma_bit; @@ -304,6 +305,7 @@ struct gdbarch startup_gdbarch = 8 * sizeof (float), 8 * sizeof (double), 8 * sizeof (long double), + 0, 8 * sizeof (void*), 8 * sizeof (void*), 8 * sizeof (void*), @@ -491,6 +493,7 @@ gdbarch_alloc (const struct gdbarch_info current_gdbarch->float_bit = 4*TARGET_CHAR_BIT; current_gdbarch->double_bit = 8*TARGET_CHAR_BIT; current_gdbarch->long_double_bit = 8*TARGET_CHAR_BIT; + current_gdbarch->long_double_bit_alternate = 0; current_gdbarch->ptr_bit = TARGET_INT_BIT; current_gdbarch->bfd_vma_bit = TARGET_ARCHITECTURE->bits_per_address; current_gdbarch->char_signed = -1; @@ -621,6 +624,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of float_bit, invalid_p == 0 */ /* Skip verify of double_bit, invalid_p == 0 */ /* Skip verify of long_double_bit, invalid_p == 0 */ + /* Skip verify of long_double_bit_alternate, invalid_p == 0 */ /* Skip verify of ptr_bit, invalid_p == 0 */ if (gdbarch->addr_bit == 0) gdbarch->addr_bit = TARGET_PTR_BIT; @@ -2404,6 +2408,14 @@ gdbarch_dump (struct gdbarch *gdbarch, s "gdbarch_dump: TARGET_LONG_DOUBLE_BIT = %d\n", TARGET_LONG_DOUBLE_BIT); #endif +#ifdef TARGET_LONG_DOUBLE_BIT_ALTERNATE + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_LONG_DOUBLE_BIT_ALTERNATE # %s\n", + XSTRING (TARGET_LONG_DOUBLE_BIT_ALTERNATE)); + fprintf_unfiltered (file, + "gdbarch_dump: TARGET_LONG_DOUBLE_BIT_ALTERNATE = %d\n", + TARGET_LONG_DOUBLE_BIT_ALTERNATE); +#endif #ifdef TARGET_LONG_DOUBLE_FORMAT fprintf_unfiltered (file, "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT # %s\n", @@ -2712,6 +2724,23 @@ set_gdbarch_long_double_bit (struct gdba int long_double_bit) { gdbarch->long_double_bit = long_double_bit; +} + +int +gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + /* Skip verify of long_double_bit_alternate, invalid_p == 0 */ + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_long_double_bit_alternate called\n"); + return gdbarch->long_double_bit_alternate; +} + +void +set_gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch, + int long_double_bit_alternate) +{ + gdbarch->long_double_bit_alternate = long_double_bit_alternate; } int Index: gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.142 diff -u -p -r1.142 gdbarch.h --- gdbarch.h 2 Feb 2003 03:16:44 -0000 1.142 +++ gdbarch.h 17 Feb 2003 16:07:19 -0000 @@ -240,6 +240,24 @@ extern void set_gdbarch_long_double_bit #endif #endif +/* Alternate number of bits in a long double for the target machine. */ + +/* Default (value) for non- multi-arch platforms. */ +#if (!GDB_MULTI_ARCH) && !defined (TARGET_LONG_DOUBLE_BIT_ALTERNATE) +#define TARGET_LONG_DOUBLE_BIT_ALTERNATE (8*TARGET_CHAR_BIT) +#endif + +extern int gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch); +extern void set_gdbarch_long_double_bit_alternate (struct gdbarch *gdbarch, int long_double_bit_alternate); +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (TARGET_LONG_DOUBLE_BIT_ALTERNATE) +#error "Non multi-arch definition of TARGET_LONG_DOUBLE_BIT_ALTERNATE" +#endif +#if GDB_MULTI_ARCH +#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (TARGET_LONG_DOUBLE_BIT_ALTERNATE) +#define TARGET_LONG_DOUBLE_BIT_ALTERNATE (gdbarch_long_double_bit_alternate (current_gdbarch)) +#endif +#endif + /* For most targets, a pointer on the target and its representation as an address in GDB have the same size and "look the same". For such a target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT @@ -2429,7 +2447,7 @@ extern void set_gdbarch_addr_bits_remove #endif #endif -/* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into +/* It is not at all clear why SMASH_TEXT_ADDRESS is not folded into ADDR_BITS_REMOVE. */ /* Default (function) for non- multi-arch platforms. */ Index: gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.194 diff -u -p -r1.194 gdbarch.sh --- gdbarch.sh 2 Feb 2003 03:16:44 -0000 1.194 +++ gdbarch.sh 17 Feb 2003 16:07:19 -0000 @@ -408,6 +408,8 @@ v:2:TARGET_FLOAT_BIT:int:float_bit::::8 v:2:TARGET_DOUBLE_BIT:int:double_bit::::8 * sizeof (double):8*TARGET_CHAR_BIT::0 # Number of bits in a long double for the target machine. v:2:TARGET_LONG_DOUBLE_BIT:int:long_double_bit::::8 * sizeof (long double):8*TARGET_CHAR_BIT::0 +# Alternate number of bits in a long double for the target machine. +v:2:TARGET_LONG_DOUBLE_BIT_ALTERNATE:int:long_double_bit_alternate::::0:0::0 # For most targets, a pointer on the target and its representation as an # address in GDB have the same size and "look the same". For such a # target, you need only set TARGET_PTR_BIT / ptr_bit and TARGET_ADDR_BIT Index: doublest.c =================================================================== RCS file: /cvs/src/src/gdb/doublest.c,v retrieving revision 1.11 diff -u -p -r1.11 doublest.c --- doublest.c 4 Dec 2002 05:40:40 -0000 1.11 +++ doublest.c 17 Feb 2003 16:07:19 -0000 @@ -633,6 +633,8 @@ floatformat_from_length (int len) return TARGET_DOUBLE_FORMAT; else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT) return TARGET_LONG_DOUBLE_FORMAT; + else if (len * TARGET_CHAR_BIT == TARGET_LONG_DOUBLE_BIT_ALTERNATE) + return TARGET_LONG_DOUBLE_FORMAT; return NULL; } Index: i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.111 diff -u -p -r1.111 i386-tdep.c --- i386-tdep.c 8 Jan 2003 15:56:36 -0000 1.111 +++ i386-tdep.c 17 Feb 2003 16:07:19 -0000 @@ -1533,6 +1533,9 @@ i386_gdbarch_init (struct gdbarch_info i bits, a `long double' actually takes up 96, probably to enforce alignment. */ set_gdbarch_long_double_bit (gdbarch, 96); + /* Allow also recognition of floating-point that has a size + of 80 bits. */ + set_gdbarch_long_double_bit_alternate (gdbarch, 80); /* NOTE: tm-i386aix.h, tm-i386bsd.h, tm-i386os9k.h, tm-ptx.h, tm-symmetry.h currently override this. Sigh. */ --=====================_358882075==_--