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 <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
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 */
* 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.