From 0d17a5a209ae80d880720fcd85b7555853605178 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Tue, 2 Feb 2010 13:14:28 +0000 Subject: [PATCH 1/1] xdr_proc_t really is different on linux26_i386 i386 Linux uses a register based calling convention within the kernel, but uses the stack for va_args based functions. This means that the hack of prototyping xdrproc_t as a va_args function doesn't work, as you end up with arguments being in the wrong place. Restore the Linux only xdrproc_t prototype that 167e1aa21f5bbea1272b239dc6518a7bdbfc3ee6 removed, add a warning to explain why its there, and modify xdr_free() so that it works without error. Change-Id: I789d387b01fcb892b187fe05f961f01c2c1f55e4 Reviewed-on: http://gerrit.openafs.org/1202 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/rx/xdr.c | 6 ++++++ src/rx/xdr.h | 11 ++++++++++- 2 files changed, 16 insertions(+), 1 deletions(-) diff --git a/src/rx/xdr.c b/src/rx/xdr.c index 4481c39..e05293e 100644 --- a/src/rx/xdr.c +++ b/src/rx/xdr.c @@ -594,6 +594,12 @@ xdr_free(xdrproc_t proc, void *obj) XDR x; x.x_op = XDR_FREE; + + /* See note in xdr.h for the method behind this madness */ +#if defined(AFS_I386_LINUX26_ENV) && defined(KERNEL) && !defined(UKERNEL) + (*proc)(&x, obj, 0); +#else (*proc)(&x, obj); +#endif } #endif /* NeXT */ diff --git a/src/rx/xdr.h b/src/rx/xdr.h index c91d17a..2936e29 100644 --- a/src/rx/xdr.h +++ b/src/rx/xdr.h @@ -174,8 +174,17 @@ enum xdr_op { * allocate dynamic storage of the appropriate size and return it. * bool_t (*xdrproc_t)(XDR *, caddr_t *); */ -typedef bool_t(*xdrproc_t) (void *, ...); +/* We need a different prototype for i386 Linux kernel code, because it + * uses a register (rather than stack) based calling convention. The + * normal va_args prototype results in the arguments being placed on the + * stack, where they aren't accessible to the 'real' function. + */ +#if defined(AFS_I386_LINUX26_ENV) && defined(KERNEL) && !defined(UKERNEL) +typedef bool_t(*xdrproc_t) (void *, caddr_t, u_int); +#else +typedef bool_t(*xdrproc_t) (void *, ...); +#endif /* * The XDR handle. -- 1.7.1