Bug 23863 - mprec buffer overwrite bug
Summary: mprec buffer overwrite bug
Status: RESOLVED FIXED
Alias: None
Product: classpath
Classification: Unclassified
Component: classpath (show other bugs)
Version: 0.18
: P2 normal
Target Milestone: 0.92
Assignee: Tom Tromey
URL:
Keywords:
: 22844 (view as bug list)
Depends on:
Blocks: 24035
  Show dependency treegraph
 
Reported: 2005-09-13 17:52 UTC by Tom Tromey
Modified: 2006-06-09 16:17 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-06-07 20:39:59


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Tromey 2005-09-13 17:52:28 UTC
Enable the assertions in mprec.c and run this code
on an x86-64 machine, and you will see an abort:

public class pr166657 {
  public long toLong(int x) { return (long) x; }
  public double doubleAt(int x) {
    return Double.longBitsToDouble(toLong(x));
  }
  public static void main(String[] args) {
    pr166657 p = new pr166657();
    System.out.println(p.doubleAt(5));
  }
}

Note that this works properly for systems where Pack_32
is defined.

I am going to check in a workaround.  Meanwhile, we should
consider updating our copy of fdlibm and mprec.  I looked
around and there appears to be a version out there that
dynamically resizes the 'x' arrays (which would solve this
problem in a general way).
Comment 1 Tom Tromey 2005-09-13 17:54:33 UTC
I forgot to mention... what happens here is that an
intermediate step in the dtoa computation requires
a buffer bigger than MAX_BIGNUM_WDS.
I don't know why this does not happen for Pack_32 platforms.
Comment 2 cvs-commit@developer.classpath.org 2005-09-15 17:14:52 UTC
Subject: Bug 23863

CVSROOT:	/cvsroot/classpath
Module name:	classpath
Branch: 	
Changes by:	Tom Tromey <tromey@savannah.gnu.org>	05/09/15 17:10:29

Modified files:
	.              : ChangeLog 
	native/fdlibm  : mprec.h 

Log message:
	Workaround for PR classpath/23863:
	* native/fdlibm/mprec.h (MAX_BIGNUM_WDS): Define as 128 on
	non-Pack_32 platforms.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/classpath/classpath/ChangeLog.diff?tr1=1.4799&tr2=1.4800&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/classpath/classpath/native/fdlibm/mprec.h.diff?tr1=1.4&tr2=1.5&r1=text&r2=text




Comment 3 Tom Tromey 2005-09-29 23:31:43 UTC
*** Bug 22844 has been marked as a duplicate of this bug. ***
Comment 4 Jakub Jelinek 2005-11-21 09:48:35 UTC
Subject: Bug 23863

Author: jakub
Date: Mon Nov 21 09:48:31 2005
New Revision: 107295

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=107295
Log:
	Workaround for PR classpath/23863:
	* java/lang/mprec.h (MAX_BIGNUM_WDS): Define as 128 on
	non-Pack_32 platforms.

Modified:
    branches/gcc-4_0-rhl-branch/libjava/ChangeLog
    branches/gcc-4_0-rhl-branch/libjava/java/lang/mprec.h

Comment 5 Mark Wielaard 2006-01-12 08:42:01 UTC
See also the following threads:
http://lists.gnu.org/archive/html/classpath-patches/2006-01/msg00141.html
http://lists.gnu.org/archive/html/classpath/2006-01/msg00073.html

newlib has updated versions of mprec.h and mprec.c at:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/stdlib/?cvsroot=src

We need a volunteer to merge our local changes back to that version.
Comment 6 cvs-commit@developer.classpath.org 2006-01-12 13:31:08 UTC
Subject: Bug 23863

CVSROOT:	/cvsroot/classpath
Module name:	classpath
Branch: 	
Changes by:	Mark Wielaard <mark@savannah.gnu.org>	06/01/12 09:26:49

Modified files:
	.              : ChangeLog 
	native/fdlibm  : mprec.c 

Log message:
	* native/fdlibm/mprec.c (Balloc): Disable assert to workaround
	PR classpath/23863.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/classpath/ChangeLog.diff?tr1=1.6018&tr2=1.6019&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/classpath/classpath/native/fdlibm/mprec.c.diff?tr1=1.6&tr2=1.7&r1=text&r2=text



Comment 7 Matthias Klose 2006-01-21 00:31:00 UTC
Subject: Bug 23863

Author: doko
Date: Sat Jan 21 00:30:57 2006
New Revision: 110058

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110058
Log:
2006-01-21  Matthias Klose  <doko@debian.org>

        Backport:
        2005-09-15  Tom Tromey  <tromey@redhat.com>
        Workaround for PR classpath/23863:
        * native/fdlibm/mprec.h (MAX_BIGNUM_WDS): Define as 128 on
        non-Pack_32 platforms.

Modified:
    branches/gcc-4_0-branch/libjava/ChangeLog
    branches/gcc-4_0-branch/libjava/java/lang/mprec.h

Comment 8 Andreas Schwab 2006-01-21 13:13:19 UTC
libjava is broken now:

../../../libjava/java/lang/mprec.h:306: error: 'MAX_BIGNUM_WDS' was not declared in this scope
make[2]: *** [java/lang/natDouble.lo] Error 1
Comment 9 Matthias Klose 2006-01-21 13:17:01 UTC
fixed in r110065
Comment 10 Tom Tromey 2006-06-07 20:39:59 UTC
I'm handling this.
Comment 11 cvs-commit@developer.classpath.org 2006-06-09 16:17:47 UTC
Subject: Bug 23863

CVSROOT:	/cvsroot/classpath
Module name:	classpath
Changes by:	Tom Tromey <tromey>	06/06/09 16:16:35

Modified files:
	.              : ChangeLog 
	native/fdlibm  : dtoa.c mprec.c mprec.h 

Log message:
		PR classpath/23863:
		* native/fdlibm/dtoa.c (_dtoa): Free contents of _Jv_reent when
		finished.
		* native/fdlibm/mprec.c: New version from newlib.  Commented out
		some includes.  Added <assert.h>.
		(_reent, _Bigint): New defines.
		(_REENT_CHECK_MP, _REENT_MP_FREELIST, _REENT_MP_P5S): Likewise.
		(__ULong, __Long): New types.
		(_calloc_r): New function.
		(Balloc): Dynamically add new _freelist entries as needed.
		* native/fdlibm/mprec.h (struct _Jv_Bigint): Don't use
		MAX_BIGNUMS to size _x[].
		(struct _Jv_reent): _freelist now a _Jv_Bigint**.  Removed
		_allocation_map, num.  Added _max_k.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpath&r1=1.7739&r2=1.7740
http://cvs.savannah.gnu.org/viewcvs/classpath/native/fdlibm/dtoa.c?cvsroot=classpath&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/classpath/native/fdlibm/mprec.c?cvsroot=classpath&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/classpath/native/fdlibm/mprec.h?cvsroot=classpath&r1=1.8&r2=1.9

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/classpath/classpath/ChangeLog,v
retrieving revision 1.7739
retrieving revision 1.7740
diff -u -b -r1.7739 -r1.7740
--- ChangeLog	9 Jun 2006 16:04:21 -0000	1.7739
+++ ChangeLog	9 Jun 2006 16:16:34 -0000	1.7740
@@ -1,3 +1,20 @@
+2006-06-09  Tom Tromey  <tromey@redhat.com>
+
+	PR classpath/23863:
+	* native/fdlibm/dtoa.c (_dtoa): Free contents of _Jv_reent when
+	finished.
+	* native/fdlibm/mprec.c: New version from newlib.  Commented out
+	some includes.  Added <assert.h>.
+	(_reent, _Bigint): New defines.
+	(_REENT_CHECK_MP, _REENT_MP_FREELIST, _REENT_MP_P5S): Likewise.
+	(__ULong, __Long): New types.
+	(_calloc_r): New function.
+	(Balloc): Dynamically add new _freelist entries as needed.
+	* native/fdlibm/mprec.h (struct _Jv_Bigint): Don't use
+	MAX_BIGNUMS to size _x[].
+	(struct _Jv_reent): _freelist now a _Jv_Bigint**.  Removed
+	_allocation_map, num.  Added _max_k.
+
 2006-06-08  Roman Kennke  <kennke@aicas.com>
 
 	* gnu/java/awt/peer/gtk/CairoGraphics2D.java

Index: native/fdlibm/dtoa.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/fdlibm/dtoa.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- native/fdlibm/dtoa.c	5 Mar 2005 14:46:53 -0000	1.4
+++ native/fdlibm/dtoa.c	9 Jun 2006 16:16:35 -0000	1.5
@@ -2,7 +2,7 @@
  *
  * The author of this software is David M. Gay.
  *
- * Copyright (c) 1991 by AT&T.
+ * Copyright (c) 1991, 2006 by AT&T.
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose without fee is hereby granted, provided that this entire notice
@@ -897,10 +897,23 @@
 {
   struct _Jv_reent reent;
   char *p;
+  int i;
+
   memset (&reent, 0, sizeof reent);
 
   p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
   strcpy (buf, p);
 
-  return;
+  for (i = 0; i < reent._result_k; ++i)
+    {
+      struct _Jv_Bigint *l = reent._freelist[i];
+      while (l)
+	{
+	  struct _Jv_Bigint *next = l->_next;
+	  free (l);
+	  l = next;
+	}
+    }
+  if (reent._freelist)
+    free (reent._freelist);
 }

Index: native/fdlibm/mprec.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/fdlibm/mprec.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- native/fdlibm/mprec.c	12 Jan 2006 09:26:49 -0000	1.7
+++ native/fdlibm/mprec.c	9 Jun 2006 16:16:35 -0000	1.8
@@ -80,72 +80,112 @@
  *	down depends on the machine and the number being converted.
  */
 
+/*#include <_ansi.h>*/
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+/* #include <reent.h> */
 #include "mprec.h"
 
 /* reent.c knows this value */
-#define _Kmax 15
-#include <stdio.h>
+/* #define _Kmax 15 */
 
-_Jv_Bigint *
-_DEFUN (Balloc, (ptr, k), struct _Jv_reent *ptr _AND int k)
-{
-  _Jv_Bigint *rv = NULL;
+#define _reent _Jv_reent
+#define _Bigint _Jv_Bigint
 
-  int i = 0;
-  int j = 1;
+#define _REENT_CHECK_MP(x)
+#define _REENT_MP_FREELIST(x) ((x)->_freelist)
+#define _REENT_MP_P5S(x) ((x)->_p5s)
 
-  /* FIXME - assert disabled because of PR classpath/23863
-   * assert ((1 << k) < MAX_BIGNUM_WDS);
-   */
+typedef unsigned long __ULong;
+typedef long __Long;
 
-  while ((ptr->_allocation_map & j) && i < MAX_BIGNUMS)
-    i++, j <<= 1;
+static void *
+_calloc_r (void *ignore, size_t x1, size_t x2)
+{
+  char *result = (char *) malloc (x1 * x2);
+  memset (result, 0, x1 * x2);
+  return result;
+}
 
-  assert (i < MAX_BIGNUMS);
+_Bigint *
+_DEFUN (Balloc, (ptr, k), struct _reent *ptr _AND int k)
+{
+  int x;
+  _Bigint *rv ;
+  int new_k = k + 1;
 
-  if (i >= MAX_BIGNUMS) 
+  _REENT_CHECK_MP(ptr);
+  if (_REENT_MP_FREELIST(ptr) == NULL)
+    {
+      /* Allocate a list of pointers to the mprec objects */
+      _REENT_MP_FREELIST(ptr) = (struct _Bigint **) _calloc_r (ptr, 
+						      sizeof (struct _Bigint *),
+							       new_k);
+      if (_REENT_MP_FREELIST(ptr) == NULL)
+	{
     return NULL;
+	}
+      ptr->_max_k = new_k;
+    }
+  else if (new_k > ptr->_max_k)
+    {
+      struct _Bigint **new_list
+	= (struct _Bigint **) realloc (ptr->_freelist,
+				       new_k * sizeof (struct _Bigint *));
+      memset (&new_list[ptr->_max_k], 0,
+	      (new_k - ptr->_max_k) * sizeof (struct _Bigint *));
+      ptr->_freelist = new_list;
+      ptr->_max_k = new_k;
 
-  ptr->_allocation_map |= j;
-  rv = &ptr->_freelist[i];
+    }
       
-  rv->_k = k;
-  rv->_maxwds = 32;
+  assert (k <= ptr->_max_k);
 
+  if ((rv = _REENT_MP_FREELIST(ptr)[k]) != 0)
+    {
+      _REENT_MP_FREELIST(ptr)[k] = rv->_next;
+    }
+  else
+    {
+      x = 1 << k;
+      /* Allocate an mprec Bigint and stick in in the freelist */
+      rv = (_Bigint *) _calloc_r (ptr,
+				  1,
+				  sizeof (_Bigint) +
+				  (x-1) * sizeof(rv->_x));
+      if (rv == NULL) return NULL;
+      rv->_k = k;
+      rv->_maxwds = x;
+    }
+  rv->_sign = rv->_wds = 0;
   return rv;
 }
 
-
 void
-_DEFUN (Bfree, (ptr, v), struct _Jv_reent *ptr _AND _Jv_Bigint * v)
+_DEFUN (Bfree, (ptr, v), struct _reent *ptr _AND _Bigint * v)
 {
-  long i;
-
-  i = v - ptr->_freelist;
-
-  assert (i >= 0 && i < MAX_BIGNUMS);
-
-  if (i >= 0 && i < MAX_BIGNUMS)
-    ptr->_allocation_map &= ~ (1 << i);
+  _REENT_CHECK_MP(ptr);
+  if (v)
+    {
+      v->_next = _REENT_MP_FREELIST(ptr)[v->_k];
+      _REENT_MP_FREELIST(ptr)[v->_k] = v;
+    }
 }
 
-
-_Jv_Bigint *
+_Bigint *
 _DEFUN (multadd, (ptr, b, m, a),
-	struct _Jv_reent *ptr _AND
-	_Jv_Bigint * b _AND
+	struct _reent *ptr _AND
+	_Bigint * b _AND
 	int m _AND
 	int a)
 {
   int i, wds;
-  unsigned long *x, y;
+  __ULong *x, y;
 #ifdef Pack_32
-  unsigned long xi, z;
+  __ULong xi, z;
 #endif
-  _Jv_Bigint *b1;
+  _Bigint *b1;
 
   wds = b->_wds;
   x = b->_x;
@@ -180,17 +220,17 @@
   return b;
 }
 
-_Jv_Bigint *
+_Bigint *
 _DEFUN (s2b, (ptr, s, nd0, nd, y9),
-	struct _Jv_reent * ptr _AND
+	struct _reent * ptr _AND
 	_CONST char *s _AND
 	int nd0 _AND
 	int nd _AND
-	unsigned long y9)
+	__ULong y9)
 {
-  _Jv_Bigint *b;
+  _Bigint *b;
   int i, k;
-  long x, y;
+  __Long x, y;
 
   x = (nd + 8) / 9;
   for (k = 0, y = 1; x > y; y <<= 1, k++);
@@ -222,7 +262,7 @@
 
 int
 _DEFUN (hi0bits,
-	(x), register unsigned long x)
+	(x), register __ULong x)
 {
   register int k = 0;
 
@@ -256,10 +296,10 @@
 }
 
 int
-_DEFUN (lo0bits, (y), unsigned long *y)
+_DEFUN (lo0bits, (y), __ULong *y)
 {
   register int k;
-  register unsigned long x = *y;
+  register __ULong x = *y;
 
   if (x & 7)
     {
@@ -298,17 +338,17 @@
     {
       k++;
       x >>= 1;
-      if (!(x & 1))
+      if (!x & 1)
 	return 32;
     }
   *y = x;
   return k;
 }
 
-_Jv_Bigint *
-_DEFUN (i2b, (ptr, i), struct _Jv_reent * ptr _AND int i)
+_Bigint *
+_DEFUN (i2b, (ptr, i), struct _reent * ptr _AND int i)
 {
-  _Jv_Bigint *b;
+  _Bigint *b;
 
   b = Balloc (ptr, 1);
   b->_x[0] = i;
@@ -316,15 +356,15 @@
   return b;
 }
 
-_Jv_Bigint *
-_DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_Bigint * b)
+_Bigint *
+_DEFUN (mult, (ptr, a, b), struct _reent * ptr _AND _Bigint * a _AND _Bigint * b)
 {
-  _Jv_Bigint *c;
+  _Bigint *c;
   int k, wa, wb, wc;
-  unsigned long carry, y, z;
-  unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+  __ULong carry, y, z;
+  __ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
 #ifdef Pack_32
-  unsigned long z2;
+  __ULong z2;
 #endif
 
   if (a->_wds < b->_wds)
@@ -350,7 +390,7 @@
 #ifdef Pack_32
   for (; xb < xbe; xb++, xc0++)
     {
-      if ((y = *xb & 0xffff))
+      if ((y = *xb & 0xffff) != 0)
 	{
 	  x = xa;
 	  xc = xc0;
@@ -366,7 +406,7 @@
 	  while (x < xae);
 	  *xc = carry;
 	}
-      if ((y = *xb >> 16))
+      if ((y = *xb >> 16) != 0)
 	{
 	  x = xa;
 	  xc = xc0;
@@ -387,7 +427,7 @@
 #else
   for (; xb < xbe; xc0++)
     {
-      if ((y = *xb++))
+      if (y = *xb++)
 	{
 	  x = xa;
 	  xc = xc0;
@@ -408,23 +448,24 @@
   return c;
 }
 
-_Jv_Bigint *
+_Bigint *
 _DEFUN (pow5mult,
-	(ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+	(ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
 {
-  _Jv_Bigint *b1, *p5, *p51;
+  _Bigint *b1, *p5, *p51;
   int i;
   static _CONST int p05[3] = {5, 25, 125};
 
-  if ((i = k & 3))
+  if ((i = k & 3) != 0)
     b = multadd (ptr, b, p05[i - 1], 0);
 
   if (!(k >>= 2))
     return b;
-  if (!(p5 = ptr->_p5s))
+  _REENT_CHECK_MP(ptr);
+  if (!(p5 = _REENT_MP_P5S(ptr)))
     {
       /* first time */
-      p5 = ptr->_p5s = i2b (ptr, 625);
+      p5 = _REENT_MP_P5S(ptr) = i2b (ptr, 625);
       p5->_next = 0;
     }
   for (;;)
@@ -447,12 +488,12 @@
   return b;
 }
 
-_Jv_Bigint *
-_DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+_Bigint *
+_DEFUN (lshift, (ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
 {
   int i, k1, n, n1;
-  _Jv_Bigint *b1;
-  unsigned long *x, *x1, *xe, z;
+  _Bigint *b1;
+  __ULong *x, *x1, *xe, z;
 
 #ifdef Pack_32
   n = k >> 5;
@@ -480,7 +521,7 @@
 	  z = *x++ >> k1;
 	}
       while (x < xe);
-      if ((*x1 = z))
+      if ((*x1 = z) != 0)
 	++n1;
     }
 #else
@@ -490,11 +531,11 @@
       z = 0;
       do
 	{
-	  *x1++ = (*x << k & 0xffff) | z;
+	  *x1++ = *x << k & 0xffff | z;
 	  z = *x++ >> k1;
 	}
       while (x < xe);
-      if ((*x1 = z))
+      if (*x1 = z)
 	++n1;
     }
 #endif
@@ -508,9 +549,9 @@
 }
 
 int
-_DEFUN (cmp, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+_DEFUN (cmp, (a, b), _Bigint * a _AND _Bigint * b)
 {
-  unsigned long *xa, *xa0, *xb, *xb0;
+  __ULong *xa, *xa0, *xb, *xb0;
   int i, j;
 
   i = a->_wds;
@@ -537,16 +578,16 @@
   return 0;
 }
 
-_Jv_Bigint *
-_DEFUN (diff, (ptr, a, b), struct _Jv_reent * ptr _AND
-	_Jv_Bigint * a _AND _Jv_Bigint * b)
+_Bigint *
+_DEFUN (diff, (ptr, a, b), struct _reent * ptr _AND
+	_Bigint * a _AND _Bigint * b)
 {
-  _Jv_Bigint *c;
+  _Bigint *c;
   int i, wa, wb;
-  long borrow, y;		/* We need signed shifts here. */
-  unsigned long *xa, *xae, *xb, *xbe, *xc;
+  __Long borrow, y;		/* We need signed shifts here. */
+  __ULong *xa, *xae, *xb, *xbe, *xc;
 #ifdef Pack_32
-  long z;
+  __Long z;
 #endif
 
   i = cmp (a, b);
@@ -625,7 +666,7 @@
 _DEFUN (ulp, (_x), double _x)
 {
   union double_union x, a;
-  register long L;
+  register __Long L;
 
   x.d = _x;
 
@@ -669,13 +710,13 @@
 
 double
 _DEFUN (b2d, (a, e),
-	_Jv_Bigint * a _AND int *e)
+	_Bigint * a _AND int *e)
 {
-  unsigned long *xa, *xa0, w, y, z;
+  __ULong *xa, *xa0, w, y, z;
   int k;
   union double_union d;
 #ifdef VAX
-  unsigned long d0, d1;
+  __ULong d0, d1;
 #else
 #define d0 word0(d)
 #define d1 word1(d)
@@ -696,7 +737,7 @@
       d0 = Exp_1 | y >> (Ebits - k);
       w = xa > xa0 ? *--xa : 0;
 #ifndef _DOUBLE_IS_32BITS
-      d1 = y << (32 - Ebits + k) | w >> (Ebits - k);
+      d1 = y << ((32 - Ebits) + k) | w >> (Ebits - k);
 #endif
       goto ret_d;
     }
@@ -720,18 +761,18 @@
   if (k < Ebits + 16)
     {
       z = xa > xa0 ? *--xa : 0;
-      d0 = Exp_1 | y << (k - Ebits) | z >> (Ebits + 16 - k);
+      d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
       w = xa > xa0 ? *--xa : 0;
       y = xa > xa0 ? *--xa : 0;
-      d1 = z << (k + 16 - Ebits) | w << (k - Ebits) | y >> (16 + Ebits - k);
+      d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
       goto ret_d;
     }
   z = xa > xa0 ? *--xa : 0;
   w = xa > xa0 ? *--xa : 0;
   k -= Ebits + 16;
-  d0 = Exp_1 | y << (k + 16) | z << k | w >> (16 - k);
+  d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
   y = xa > xa0 ? *--xa : 0;
-  d1 = w << (k + 16) | y << k;
+  d1 = w << k + 16 | y << k;
 #endif
 ret_d:
 #ifdef VAX
@@ -744,22 +785,24 @@
   return d.d;
 }
 
-_Jv_Bigint *
+_Bigint *
 _DEFUN (d2b,
 	(ptr, _d, e, bits),
-	struct _Jv_reent * ptr _AND
+	struct _reent * ptr _AND
 	double _d _AND
 	int *e _AND
 	int *bits)
 
 {
   union double_union d;
-  _Jv_Bigint *b;
+  _Bigint *b;
   int de, i, k;
-  unsigned long *x, y, z;
+  __ULong *x, y, z;
 #ifdef VAX
-  unsigned long d0, d1;
+  __ULong d0, d1;
+#endif
   d.d = _d;
+#ifdef VAX
   d0 = word0 (d) >> 16 | word0 (d) << 16;
   d1 = word1 (d) >> 16 | word1 (d) << 16;
 #else
@@ -783,14 +826,16 @@
   z |= Exp_msk11;
 #endif
 #else
-  if ((de = (int) (d0 >> Exp_shift)))
+  if ((de = (int) (d0 >> Exp_shift)) != 0)
     z |= Exp_msk1;
 #endif
 #ifdef Pack_32
 #ifndef _DOUBLE_IS_32BITS
-  if ((y = d1))
+  if (d1)
     {
-      if ((k = lo0bits (&y)))
+      y = d1;
+      k = lo0bits (&y);
+      if (k)
 	{
 	  x[0] = y | z << (32 - k);
 	  z >>= k;
@@ -814,22 +859,24 @@
 #endif
     }
 #else
-  if ((y = d1))
+  if (d1)
     {
-      if ((k = lo0bits (&y)))
+      y = d1;
+      k = lo0bits (&y);
+      if (k)
 	if (k >= 16)
 	  {
-	    x[0] = y | (z << (32 - k) & 0xffff);
-	    x[1] = z >> (k - 16) & 0xffff;
+	    x[0] = y | z << 32 - k & 0xffff;
+	    x[1] = z >> k - 16 & 0xffff;
 	    x[2] = z >> k;
 	    i = 2;
 	  }
 	else
 	  {
 	    x[0] = y & 0xffff;
-	    x[1] = (y >> 16 | z << (16 - k)) & 0xffff;
+	    x[1] = y >> 16 | z << 16 - k & 0xffff;
 	    x[2] = z >> k & 0xffff;
-	    x[3] = z >> (k + 16);
+	    x[3] = z >> k + 16;
 	    i = 3;
 	  }
       else
@@ -894,7 +941,7 @@
 #undef d1
 
 double
-_DEFUN (ratio, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+_DEFUN (ratio, (a, b), _Bigint * a _AND _Bigint * b)
 
 {
   union double_union da, db;
@@ -958,3 +1005,17 @@
 #endif
 
 
+double
+_DEFUN (_mprec_log10, (dig),
+	int dig)
+{
+  double v = 1.0;
+  if (dig < 24)
+    return tens[dig];
+  while (dig > 0)
+    {
+      v *= 10;
+      dig--;
+    }
+  return v;
+}

Index: native/fdlibm/mprec.h
===================================================================
RCS file: /cvsroot/classpath/classpath/native/fdlibm/mprec.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- native/fdlibm/mprec.h	4 Jan 2006 16:37:55 -0000	1.8
+++ native/fdlibm/mprec.h	9 Jun 2006 16:16:35 -0000	1.9
@@ -282,7 +282,7 @@
 {
   struct _Jv_Bigint *_next;
   int _k, _maxwds, _sign, _wds;
-  unsigned long _x[MAX_BIGNUM_WDS];
+  unsigned long _x[1];
 };
 
 
@@ -310,10 +310,8 @@
   int _result_k;
   struct _Jv_Bigint *_p5s;
 
-  struct _Jv_Bigint _freelist[MAX_BIGNUMS];
-  int _allocation_map;
-
-  int num;
+  struct _Jv_Bigint **_freelist;
+  int _max_k;
 };
 
 



Comment 12 Tom Tromey 2006-06-09 16:17:55 UTC
Fix checked in.
Comment 13 Tom Tromey 2006-06-09 16:19:39 UTC
Subject: Bug 23863

Author: tromey
Date: Fri Jun  9 16:18:51 2006
New Revision: 114511

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=114511
Log:
	PR classpath/23863:
	* native/fdlibm/dtoa.c (_dtoa): Free contents of _Jv_reent when
	finished.
	* native/fdlibm/mprec.c: New version from newlib.  Commented out
	some includes.  Added <assert.h>.
	(_reent, _Bigint): New defines.
	(_REENT_CHECK_MP, _REENT_MP_FREELIST, _REENT_MP_P5S): Likewise.
	(__ULong, __Long): New types.
	(_calloc_r): New function.
	(Balloc): Dynamically add new _freelist entries as needed.
	* native/fdlibm/mprec.h (struct _Jv_Bigint): Don't use
	MAX_BIGNUMS to size _x[].
	(struct _Jv_reent): _freelist now a _Jv_Bigint**.  Removed
	_allocation_map, num.  Added _max_k.

Modified:
    trunk/libjava/classpath/ChangeLog.gcj
    trunk/libjava/classpath/native/fdlibm/dtoa.c
    trunk/libjava/classpath/native/fdlibm/mprec.c
    trunk/libjava/classpath/native/fdlibm/mprec.h