From owner-freebsd-bugs Thu Apr 6 12:40:11 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 8903237BAF4 for ; Thu, 6 Apr 2000 12:40:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id MAA78198; Thu, 6 Apr 2000 12:40:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Date: Thu, 6 Apr 2000 12:40:03 -0700 (PDT) Message-Id: <200004061940.MAA78198@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: "David E. Cross" Subject: Re: bin/17681: XDR does not handle 64bit data types correctly Reply-To: "David E. Cross" Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/17681; it has been noted by GNATS. From: "David E. Cross" To: Sheldon Hearn Cc: "David E. Cross" , 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 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