Date: Tue, 24 Apr 2012 12:37:09 +0300 From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua> To: Sebastian Huber <sebastian.huber@embedded-brains.de> Cc: freebsd-hackers@freebsd.org Subject: Re: XDR Library and Short Enums Message-ID: <20120424093709.GA9857@pm513-1.comsys.ntu-kpi.kiev.ua> In-Reply-To: <4F8C1082.3020801@embedded-brains.de> References: <4F8C1082.3020801@embedded-brains.de>
next in thread | previous in thread | raw e-mail | index | archive | help
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 <err.h> #include <stdio.h> #include <rpc/types.h> #include <rpc/xdr.h> #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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120424093709.GA9857>