This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Support alternate 'long double' size.


  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  <muller@ics.u-strasbg.fr>

	* 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.
	
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.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]