Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Apr 2000 12:40:03 -0700 (PDT)
From:      "David E. Cross" <crossd@cs.rpi.edu>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/17681: XDR does not handle 64bit data types correctly 
Message-ID:  <200004061940.MAA78198@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/17681; it has been noted by GNATS.

From: "David E. Cross" <crossd@cs.rpi.edu>
To: Sheldon Hearn <sheldonh@uunet.co.za>
Cc: "David E. Cross" <crossd@cs.rpi.edu>,
	FreeBSD-gnats-submit@FreeBSD.ORG, crossd@cs.rpi.edu
Subject: Re: bin/17681: XDR does not handle 64bit data types correctly 
Date: Thu, 06 Apr 2000 14:19:01 -0400

 Hmm.. I feel one of us is probably doing something stupid :)
 
 This is a bit long as it includes the multiple copies of the source to
 try to clear things up (only the XDR64 routines are here, as that is
 the only thing I touched.)
 
 The XDR patch that I gave out only touches the 64bit routines in the
 XDR library, so here is the XDR library before my patch:
 
 /*
  * XDR 64-bit integers
  */
 bool_t
 xdr_int64_t(xdrs, int64_p)
         register XDR *xdrs;
         int64_t *int64_p;
 {
         int64_t x;
 
         switch (xdrs->x_op) {
 
         case XDR_ENCODE:
                 return (xdr_opaque(xdrs, (caddr_t)int64_p, sizeof(int64_t)));
 
         case XDR_DECODE:
                 if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
                         return (FALSE);
                 }
                 *int64_p = x;
                 return (TRUE);
 
         case XDR_FREE:
                 return (TRUE);
         }
         return (FALSE);
 }
 
 /*
  * XDR unsigned 64-bit integers
  */
 bool_t
 xdr_u_int64_t(xdrs, uint64_p)
         register XDR *xdrs;
         u_int64_t *uint64_p;
 {
         u_int64_t x;
 
         switch (xdrs->x_op) {
 
         case XDR_ENCODE:
                 return (xdr_opaque(xdrs, (caddr_t)uint64_p, sizeof(u_int64_t)));
 
         case XDR_DECODE:
                 if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
                         return (FALSE);
                 }
                 *uint64_p = x;
                 return (TRUE);
 
         case XDR_FREE:
                 return (TRUE);
         }
         return (FALSE);
 }
 
 
 The following is from:
 http://www.freebsd.org/cgi/cvsweb.cgi/basesrc/lib/libc/rpc/xdr.c?rev=1.21&cvsroot=netbsd
 
 /*
  * XDR 64-bit integers
  */
 bool_t
 xdr_int64_t(xdrs, llp)
         XDR *xdrs;
         int64_t *llp;
 {
         u_long ul[2];
 
         switch (xdrs->x_op) {
         case XDR_ENCODE:
                 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
                 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
                 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
         case XDR_DECODE:
                 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
                         return (FALSE);
                 *llp = (int64_t)
                     (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
                 return (TRUE);
         case XDR_FREE:
                 return (TRUE);
         }
         /* NOTREACHED */
         return (FALSE);
 }
 
 
 /*
  * XDR unsigned 64-bit integers
  */
 bool_t
 xdr_u_int64_t(xdrs, ullp)
         XDR *xdrs;
         u_int64_t *ullp;
 {
         u_long ul[2];
 
         switch (xdrs->x_op) {
         case XDR_ENCODE:
                 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
                 ul[1] = (u_long)(*ullp) & 0xffffffff;
                 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
         case XDR_DECODE:
                 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
                         return (FALSE);
                 *ullp = (u_int64_t)
                     (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
                 return (TRUE);
         case XDR_FREE:
                 return (TRUE);
         }
         /* NOTREACHED */
         return (FALSE);
 }
 
 The following is a result of:
 patch <xdr.diff
 
 /*
  * XDR 64-bit integers
  */
 bool_t
 xdr_int64_t(xdrs, int64_p)
         register XDR *xdrs;
         int64_t *int64_p;
 {
         u_long ul[2];
 
         switch (xdrs->x_op) {
 
         case XDR_ENCODE:
                 ul[0] = (u_long)((u_int64_t)*int64_p >> 32) & 0xffffffff;
                 ul[1] = (u_long)((u_int64_t)*int64_p) & 0xffffffff;
                 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
         case XDR_DECODE:
                 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
                         return (FALSE);
                 *int64_p = (int64_t)
                         (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
                 return (TRUE);
         case XDR_FREE:
                 return (TRUE);
         }
         return (FALSE);
 }
 
 /*
  * XDR unsigned 64-bit integers
  */
 bool_t
 xdr_u_int64_t(xdrs, uint64_p)
         register XDR *xdrs;
         u_int64_t *uint64_p;
 {
         u_long ul[2];
 
         switch (xdrs->x_op) {
 
         case XDR_ENCODE:
                 ul[0] = (u_long)(*int64_p >> 32) & 0xffffffff;
                 ul[1] = (u_long)(*int64_p) & 0xffffffff;
                 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
 
         case XDR_DECODE:
                 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
                         return (FALSE);
                 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
                         return (FALSE);
                 *int64_p = (u_int64_t)
                         (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
                 return (TRUE);
         case XDR_FREE:
                 return (TRUE);
         }
         return (FALSE);
 }
 
 So, if we save the NetBSD and the patched FreeBSD xdr.c (just the XDR64
 routeines) to a file, and diff them we get:
 
 1,2d0
 < 
 < 
 7,9c5,7
 < xdr_int64_t(xdrs, llp)
 <         XDR *xdrs;
 <         int64_t *llp;
 ---
 > xdr_int64_t(xdrs, int64_p)
 >         register XDR *xdrs;
 >         int64_t *int64_p;
 13a12
 > 
 15,16c14,15
 <                 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
 <                 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
 ---
 >                 ul[0] = (u_long)((u_int64_t)*int64_p >> 32) & 0xffffffff;
 >                 ul[1] = (u_long)((u_int64_t)*int64_p) & 0xffffffff;
 25,26c24,25
 <                 *llp = (int64_t)
 <                     (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
 ---
 >                 *int64_p = (int64_t)
 >                         (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
 31d29
 <         /* NOTREACHED */
 35d32
 < 
 40,42c37,39
 < xdr_u_int64_t(xdrs, ullp)
 <         XDR *xdrs;
 <         u_int64_t *ullp;
 ---
 > xdr_u_int64_t(xdrs, uint64_p)
 >         register XDR *xdrs;
 >         u_int64_t *uint64_p;
 46a44
 > 
 48,49c46,47
 <                 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
 <                 ul[1] = (u_long)(*ullp) & 0xffffffff;
 ---
 >                 ul[0] = (u_long)(*int64_p >> 32) & 0xffffffff;
 >                 ul[1] = (u_long)(*int64_p) & 0xffffffff;
 52a51
 > 
 58,59c57,58
 <                 *ullp = (u_int64_t)
 <                     (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
 ---
 >                 *int64_p = (u_int64_t)
 >                         (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
 64d62
 <         /* NOTREACHED */
 
 The only differences that I am seeing in the file are naming conventions.
 I decided to stick with ours.  The NetBSD people have the 64bit type as the
 long long and the unsigned long long,  where we have the int64_t and
 u_int64_t.  They make mention of this being non-portable, and thus in its
 own secion.  As we have the 'int64_t' I decided to stick with it.
 
 I will ask the lockd devloper to do an additional set of runs 
 just to make absolutely, 100%, definitely, undeniably, sure.
 
 --
 David Cross                               | email: crossd@cs.rpi.edu 
 Lab Director                              | Rm: 308 Lally Hall
 Rensselaer Polytechnic Institute,         | Ph: 518.276.2860            
 Department of Computer Science            | Fax: 518.276.4033
 I speak only for myself.                  | WinNT:Linux::Linux:FreeBSD
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200004061940.MAA78198>