From owner-freebsd-hackers@FreeBSD.ORG Sat Aug 30 20:27:35 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EFD7216A4BF for ; Sat, 30 Aug 2003 20:27:34 -0700 (PDT) Received: from smtp.eos.ocn.ne.jp (eos.ocn.ne.jp [211.6.83.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id B22F443F75 for ; Sat, 30 Aug 2003 20:27:33 -0700 (PDT) (envelope-from hrs@eos.ocn.ne.jp) Received: from mail.d.allbsd.org (p38078-adsao12honb4-acca.tokyo.ocn.ne.jp [219.161.135.78]) by smtp.eos.ocn.ne.jp (Postfix) with ESMTP id AE4E5F0A for ; Sun, 31 Aug 2003 12:27:32 +0900 (JST) Received: from localhost (alph.allbsd.org [192.168.0.10]) h7V3QqIF057819 for ; Sun, 31 Aug 2003 12:26:53 +0900 (JST) (envelope-from hrs@eos.ocn.ne.jp) Date: Sun, 31 Aug 2003 12:22:19 +0900 (JST) Message-Id: <20030831.122219.15218794.hrs@eos.ocn.ne.jp> To: hackers@freebsd.org From: Hiroki Sato X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 3.3 on Emacs 20.7 / Mule 4.0 (HANANOEN) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Subject: initstate() on FreeBSD/sparc64 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Aug 2003 03:27:35 -0000 Hi, I noticed that initstate() caused memory corruption on FreeBSD/sparc64. I guess this is because lib/libc/stdlib/random.c assumes "long" is 32-bit long. The attached patch works fine on my box, but this is a bit ugly. Could anyone take care of this? -- | Hiroki SATO / Index: random.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdlib/random.c,v retrieving revision 1.23 diff -d -u -I\$FreeBSD:.*\$ -I\$NetBSD:.*\$ -I\$OpenBSD:.*\$ -I\$Id:.*\$ -I\$hrs:.*\$ -r1.23 random.c --- random.c 10 Aug 2003 17:49:55 -0000 1.23 +++ random.c 31 Aug 2003 03:00:04 -0000 @@ -61,10 +61,10 @@ * congruential generator. If the amount of state information is less than * 32 bytes, a simple linear congruential R.N.G. is used. * - * Internally, the state information is treated as an array of longs; the + * Internally, the state information is treated as an array of ints; the * zeroeth element of the array is the type of R.N.G. being used (small * integer); the remainder of the array is the state information for the - * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of + * R.N.G. Thus, 32 bytes of state information will give 7 ints worth of * state information, which will allow a degree seven polynomial. (Note: * the zeroeth word of state information also has some other information * stored in it -- see setstate() for details). @@ -148,8 +148,8 @@ #define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */ #endif /* !USE_WEAK_SEEDING */ -static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; -static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; +static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; +static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; /* * Initially, everything is set up as if from: @@ -165,7 +165,7 @@ * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. */ -static long randtbl[DEG_3 + 1] = { +static int randtbl[DEG_3 + 1] = { TYPE_3, #ifdef USE_WEAK_SEEDING /* Historic implementation compatibility */ @@ -200,8 +200,8 @@ * in the initialization of randtbl) because the state table pointer is set * to point to randtbl[1] (as explained below). */ -static long *fptr = &randtbl[SEP_3 + 1]; -static long *rptr = &randtbl[1]; +static int *fptr = &randtbl[SEP_3 + 1]; +static int *rptr = &randtbl[1]; /* * The following things are the pointer to the state information table, the @@ -213,11 +213,11 @@ * this is more efficient than indexing every time to find the address of * the last element to see if the front and rear pointers have wrapped. */ -static long *state = &randtbl[1]; -static long rand_type = TYPE_3; -static long rand_deg = DEG_3; -static long rand_sep = SEP_3; -static long *end_ptr = &randtbl[DEG_3 + 1]; +static int *state = &randtbl[1]; +static int rand_type = TYPE_3; +static int rand_deg = DEG_3; +static int rand_sep = SEP_3; +static int *end_ptr = &randtbl[DEG_3 + 1]; static inline long good_rand(long); @@ -350,7 +350,7 @@ * * Returns a pointer to the old state. * - * Note: The Sparc platform requires that arg_state begin on a long + * Note: The Sparc platform requires that arg_state begin on an int * word boundary; otherwise a bus error will occur. Even so, lint will * complain about mis-alignment, but you should disregard these messages. */ @@ -361,12 +361,12 @@ long n; /* # bytes of state info */ { char *ostate = (char *)(&state[-1]); - long *long_arg_state = (long *) arg_state; + int *int_arg_state = (int *)(void *)arg_state; if (rand_type == TYPE_0) state[-1] = rand_type; else - state[-1] = MAX_TYPES * (rptr - state) + rand_type; + state[-1] = MAX_TYPES * (int)(rptr - state) + rand_type; if (n < BREAK_0) { (void)fprintf(stderr, "random: not enough state (%ld bytes); ignored.\n", n); @@ -393,13 +393,13 @@ rand_deg = DEG_4; rand_sep = SEP_4; } - state = (long *) (long_arg_state + 1); /* first location */ + state = (int *) (int_arg_state + 1); /* first location */ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ - srandom(seed); + srandom((unsigned int)seed); if (rand_type == TYPE_0) - long_arg_state[0] = rand_type; + int_arg_state[0] = rand_type; else - long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type; + int_arg_state[0] = MAX_TYPES * (int)(rptr - state) + rand_type; return(ostate); } @@ -426,7 +426,7 @@ setstate(arg_state) char *arg_state; /* pointer to state array */ { - long *new_state = (long *) arg_state; + int *new_state = (int *)(void *)arg_state; long type = new_state[0] % MAX_TYPES; long rear = new_state[0] / MAX_TYPES; char *ostate = (char *)(&state[-1]); @@ -434,7 +434,7 @@ if (rand_type == TYPE_0) state[-1] = rand_type; else - state[-1] = MAX_TYPES * (rptr - state) + rand_type; + state[-1] = MAX_TYPES * (int)(rptr - state) + rand_type; switch(type) { case TYPE_0: case TYPE_1: @@ -449,7 +449,7 @@ (void)fprintf(stderr, "random: state info corrupted; not changed.\n"); } - state = (long *) (new_state + 1); + state = (int *) (new_state + 1); if (rand_type != TYPE_0) { rptr = &state[rear]; fptr = &state[(rear + rand_sep) % rand_deg]; @@ -478,8 +478,8 @@ long random() { - long i; - long *f, *r; + int i; + int *f, *r; if (rand_type == TYPE_0) { i = state[0]; @@ -490,7 +490,8 @@ */ f = fptr; r = rptr; *f += *r; - i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */ + /* chucking least random bit */ + i = ((unsigned int)*f >> 1) & 0x7fffffff; if (++f >= end_ptr) { f = state; ++r;