From owner-freebsd-hackers@FreeBSD.ORG Tue Apr 24 09:37:12 2012 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9014F1065680 for ; Tue, 24 Apr 2012 09:37:12 +0000 (UTC) (envelope-from simon@comsys.ntu-kpi.kiev.ua) Received: from comsys.kpi.ua (comsys.kpi.ua [77.47.192.42]) by mx1.freebsd.org (Postfix) with ESMTP id 0FD2A8FC17 for ; Tue, 24 Apr 2012 09:37:11 +0000 (UTC) Received: from pm513-1.comsys.kpi.ua ([10.18.52.101] helo=pm513-1.comsys.ntu-kpi.kiev.ua) by comsys.kpi.ua with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.63) (envelope-from ) id 1SMcBJ-0001MJ-PC; Tue, 24 Apr 2012 12:37:09 +0300 Received: by pm513-1.comsys.ntu-kpi.kiev.ua (Postfix, from userid 1001) id C42761CC31; Tue, 24 Apr 2012 12:37:09 +0300 (EEST) Date: Tue, 24 Apr 2012 12:37:09 +0300 From: Andrey Simonenko To: Sebastian Huber Message-ID: <20120424093709.GA9857@pm513-1.comsys.ntu-kpi.kiev.ua> References: <4F8C1082.3020801@embedded-brains.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4F8C1082.3020801@embedded-brains.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-Authenticated-User: simon@comsys.ntu-kpi.kiev.ua X-Authenticator: plain X-Sender-Verify: SUCCEEDED (sender exists & accepts mail) X-Exim-Version: 4.63 (build at 28-Apr-2011 07:11:12) X-Date: 2012-04-24 12:37:09 X-Connected-IP: 10.18.52.101:23220 X-Message-Linecount: 154 X-Body-Linecount: 139 X-Message-Size: 4336 X-Body-Size: 3692 Cc: freebsd-hackers@freebsd.org Subject: Re: XDR Library and Short Enums X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Apr 2012 09:37:12 -0000 On Mon, Apr 16, 2012 at 02:28:50PM +0200, Sebastian Huber wrote: > Hi, > > the XDR library implementation of xdr_enum() is currently: > > /* > * XDR enumerations > */ > bool_t > xdr_enum(XDR *xdrs, enum_t *ep) > { > enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ > > /* > * enums are treated as ints > */ > /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) { > return (xdr_long(xdrs, (long *)(void *)ep)); > } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) { > return (xdr_int(xdrs, (int *)(void *)ep)); > } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) { > return (xdr_short(xdrs, (short *)(void *)ep)); > } else { > return (FALSE); > } > } > > The enum_t is defined as: > > typedef int32_t enum_t; > > This is problematic with short enums (variable sized enums). I case of short > enums sizeof (enum sizecheck) would be 1. The ARM EABI lets you a choice > between two alternatives described in the document issued by ARM. See also > section 7.1.3 "Enumerated Types" > > http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf > > How would you implement and use the XDR library with short enums? The > xdr_enum() can be easily changed to: > > /* > * XDR enumerations > */ > bool_t > xdr_enum(XDR *xdrs, enum_t *ep) > { > /* > * enums are treated as ints > */ > /* LINTED */ if (sizeof (enum_t) == sizeof (long)) { > return (xdr_long(xdrs, (long *)(void *)ep)); > } else /* LINTED */ if (sizeof (enum_t) == sizeof (int)) { > return (xdr_int(xdrs, (int *)(void *)ep)); > } else /* LINTED */ if (sizeof (enum_t) == sizeof (short)) { > return (xdr_short(xdrs, (short *)(void *)ep)); > } else { > return (FALSE); > } > } > > The problem is in the XDR library usage. An example is this (rpc_msg.h): > > enum msg_type { > CALL=0, > REPLY=1 > }; > > How would you fix this? What about > > enum msg_type { > CALL=0, > REPLY=1, > _MSG_TYPE_INVALID = 0xffffffff > }; > RFC1832 and RFC4506 specify enumerations: Enumerations have the same representation as signed integers. Enumerations are handy for describing subsets of the integers. and specify signed integers: An XDR signed integer is a 32-bit datum that encodes an integer in the range [-2147483648,2147483647]. Can somebody explain why xdr_enum() implementation has such logic that does not correspond to the description of XDR enumeration type in the above mentioned RFCs? Another question. xdr_long() translates C 'long' integers to their external representation. Actually it converts C 'long' integer to uint32_t, obviously such conversion is incorrect. Is is expected that the given value of 'long' type in xdr_long() will fit to uint32_t type and is not negative? Example: ------------------------------------------------------------------- #include #include #include #include #define BUF_SIZE 1024 int main(void) { char buf[BUF_SIZE] = {}; XDR xdrs1, xdrs2; long x1, x2, y1, y2; xdrmem_create(&xdrs1, buf, sizeof(buf), XDR_ENCODE); xdrmem_create(&xdrs2, buf, sizeof(buf), XDR_DECODE); x1 = 0x0123456789abcdefL; x2 = -1; if (xdr_long(&xdrs1, &x1) == FALSE || xdr_long(&xdrs1, &x2) == FALSE) err(1, "xdr_long(xdrs1)"); if (xdr_long(&xdrs2, &y1) == FALSE || xdr_long(&xdrs2, &y2) == FALSE) err(1, "xdr_long(xdrs2)"); printf("x1 = 0x%016lx\ny1 = 0x%016lx\n", x1, y1); printf("x2 = %ld\ny2 = %ld\n", x2, y2); return (0); } ------------------------------------------------------------------- Running it on amd64: x1 = 0x0123456789abcdef y1 = 0x0000000089abcdef x2 = -1 y2 = 4294967295