[PATCH 1/1] Make xdrproc_t non-variadic

Jonas Bonn jonas at southpole.se
Wed Jun 9 10:07:57 UTC 2010


Casting a non-variadic function to a variadic type is not permitted in C and
results in undefined behaviour.  Although it may work for some architectures,
on the OR32 architecture (and for others, from what I can find through Google),
the parameters are passed differently depending on whether the function is
declared varidic or not, thus casting between the two types results in
failure.

Specifically, the following is not permitted:

/* Define non-variadic function */
int foo(int x, int y) {
	...
}

typedef int (*bar_t)(int x, int y, ...);

void f() {
	int x,y;
	bar_t bar;

	/* Cast foo to variadic type... not allowed */
	bar = (bar_t) foo;
	(*bar)(x,y);
}

This patch redeclares the xdrproc_t to be non-variadic.  None of the functions
that are cast to xdrproc_t in uClibc are actually variadic; this applies to
Busybox, as well.

Signed-off-by: Jonas Bonn <jonas at southpole.se>
---
 include/rpc/xdr.h             |    2 +-
 libc/inet/rpc/xdr.c           |    4 ++--
 libc/inet/rpc/xdr_array.c     |    4 ++--
 libc/inet/rpc/xdr_reference.c |    2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/rpc/xdr.h b/include/rpc/xdr.h
index 9981e3a..4b663d7 100644
--- a/include/rpc/xdr.h
+++ b/include/rpc/xdr.h
@@ -159,7 +159,7 @@ struct XDR
  * allocate dynamic storage of the appropriate size and return it.
  * bool_t       (*xdrproc_t)(XDR *, caddr_t *);
  */
-typedef bool_t (*xdrproc_t) (XDR *, void *,...);
+typedef bool_t (*xdrproc_t) (XDR *, void *);
 
 
 /*
diff --git a/libc/inet/rpc/xdr.c b/libc/inet/rpc/xdr.c
index 78f4d04..5aec83e 100644
--- a/libc/inet/rpc/xdr.c
+++ b/libc/inet/rpc/xdr.c
@@ -633,14 +633,14 @@ xdr_union (XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choice
   for (; choices->proc != NULL_xdrproc_t; choices++)
     {
       if (choices->value == dscm)
-	return (*(choices->proc)) (xdrs, unp, LASTUNSIGNED);
+	return (*(choices->proc)) (xdrs, unp);
     }
 
   /*
    * no match - execute the default xdr routine if there is one
    */
   return ((dfault == NULL_xdrproc_t) ? FALSE :
-	  (*dfault) (xdrs, unp, LASTUNSIGNED));
+	  (*dfault) (xdrs, unp));
 }
 libc_hidden_def(xdr_union)
 
diff --git a/libc/inet/rpc/xdr_array.c b/libc/inet/rpc/xdr_array.c
index bb3e51e..a80e11c 100644
--- a/libc/inet/rpc/xdr_array.c
+++ b/libc/inet/rpc/xdr_array.c
@@ -125,7 +125,7 @@ xdr_array (XDR *xdrs, caddr_t *addrp, u_int *sizep, u_int maxsize, u_int elsize,
    */
   for (i = 0; (i < c) && stat; i++)
     {
-      stat = (*elproc) (xdrs, target, LASTUNSIGNED);
+      stat = (*elproc) (xdrs, target);
       target += elsize;
     }
 
@@ -165,7 +165,7 @@ xdr_vector (xdrs, basep, nelem, elemsize, xdr_elem)
   elptr = basep;
   for (i = 0; i < nelem; i++)
     {
-      if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED))
+      if (!(*xdr_elem) (xdrs, elptr))
 	{
 	  return FALSE;
 	}
diff --git a/libc/inet/rpc/xdr_reference.c b/libc/inet/rpc/xdr_reference.c
index 937b0cc..9ef0eb4 100644
--- a/libc/inet/rpc/xdr_reference.c
+++ b/libc/inet/rpc/xdr_reference.c
@@ -97,7 +97,7 @@ xdr_reference (XDR *xdrs, caddr_t *pp, u_int size, xdrproc_t proc)
 	break;
       }
 
-  stat = (*proc) (xdrs, loc, LASTUNSIGNED);
+  stat = (*proc) (xdrs, loc);
 
   if (xdrs->x_op == XDR_FREE)
     {
-- 
1.7.0.4



More information about the uClibc mailing list