Date: Thu, 22 Apr 2004 08:11:06 -0700 From: "David O'Brien" <obrien@freebsd.org> To: freebsd-amd64@freebsd.org Subject: Re: va_list q Message-ID: <20040422151106.GC78422@dragon.nuxi.com> In-Reply-To: <200404212258.01563.peter@wemm.org> References: <20040422050128.GQ34647@lucky.net> <200404212258.01563.peter@wemm.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Apr 21, 2004 at 10:58:01PM -0700, Peter Wemm wrote: > > int > > vslprintf(buf, buflen, fmt, args) > > [...] > > #ifndef __powerpc__ > > > n = vslprintf(buf, buflen + 1, f, va_arg(args, > > > va_list)); > > #else > > /* On the powerpc, a va_list is an array of 1 structure > > */ n = vslprintf(buf, buflen + 1, f, va_arg(args, void *)); #endif ... > amd64 needs to use the same code that is in the #ifdef __powerpc__. Its > what we use in src/usr.sbin/pppd FWIW. ... > As an aside, this breaks code that assums it can copy va_lists by > assignment. On powerpc and amd64, you *must* use va_copy(), or you > simply copy the pointer, not the actual argument passing state. If we step back a little, the code breaks because it is not ISO-C compliant. One must use va_copy() just like one needs to use strcpy() to get a unique copy of a C string. There is zero need for the "#ifdef __powerpc__" -- that code is ISO-C compliant and should work on all platforms. 1. Adhere to ISO C specification for stdargs: Do not copy ap directly: void foo (va_list ap) { va_list tap = ap; /* use tap */ } Correct usage: #include <stdargs.h> void foo (va_list ap) { va_list tap; va_copy (tap, ap); /* use tap */ } GCCs ap is a pointer for AMD64. &ap does not do what you may expect. REVIEW ISO C99 STANDARD, SECTION 7.15. 2. Correct Prototypes when using stdargs By convention, GCC stdargs and varargs on AMD64 use the %al register to indicate the number of floating-point arguments. The entry point of a function using stdargs or varargs, expects the %al register to be initialized properly. If the function prototype used by caller doesn't include the (...), gcc won't initialize %al as part of the call. And a crash and/or strange behavior will occur after the call. -- -- David (obrien@FreeBSD.org)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040422151106.GC78422>