varargs ABI & PPC (problems porting cdrecord to Linux-ppc)

Joerg Schilling schilling@fokus.gmd.de
Tue Feb 17 14:38:00 GMT 1998


While porting cdreocrd to Linux-ppc, I found a problem that is related to
the fact that Linux-ppc uses the SVr4 varargs ABI.

I append the README.ppc that I wrote for this reason to illustrate the problem.

It would be nice if GCC could add the va_copy() Solaris varargs enhancement
in future.

Joerg


/*--------------------------------------------------------------------------*/
If your system uses the SVr4 ABI (designed by Motorola), you will only
be able to compile my library files lib/format.c and lib/getargs.c if your
C-compiler supports the macro va_copy() from stdarg.h.

Mach/Next STep/Apple Rhapsody on ppc use a 'void *' for the type va_list
so you don't need to make changes on these systems.

Solaris/ppc (made in 1992) is the first UNIX implementation for the PPC.
It includes the va_copy() macro that allows you to assign a C object of the
type va_list in a system independant way.

Linux/ppc uses exactly the same construct as Solaris for the type va_list
but unfortunately does not include the macro va_copy().

Here is what Solaris /usr/include/sys/varargs.h looks like:

/*
 * va_copy is a Solaris extension to provide a portable way to perform
 * a variable argument list ``bookmarking'' function.
 */
#if defined(__ppc)
#define	va_copy(to, from)	((to)[0] = (from)[0])
#else
#define	va_copy(to, from)	((to) = (from))
#endif

If you don't have this, you will never be able to compile recent printf()
implementations that allow you to have localized commands that need to
exchange the positions of arguments in different languages. If you don't
know this feature, here is a simple example:

main()
{
	printf("'%1$s' '%2$i'\n",	"test",	8);
	printf("'%2$s' '%1$i'\n",	8,	"test");
}

Will print:

'test' '8'
'test' '8'


To be able to compile my lib/format.c and lib/getargs.c on a OS
implementation that uses an array for va_list, you will need
this va_copy() enhancement too.

The files mentioned above already compile on a PPC Apple Rhapsody system.
But as mentioned before, Rhapsody uses a void * for va_list (maybe because
Apple includes badly designed international printf code from BSD 4.4
that requires va_list to be void * to work).

GCC
===

To be able to compile a SVr4 compliant printf, or my files lib/format.c and
lib/getargs.c with GCC, you will need to add the following definition 
to va-ppc.h :

/usr/lib/gcc-lib/*-linux-gnulibc1/2.*/include/va-ppc.h

#define	va_copy(to, from)	((to)[0] = (from)[0])

and to all other va-*.h files:

#define	va_copy(to, from)	((to) = (from))

This problem has been mailed to the egcs/GCC folks too.

Joerg

http://www.fokus.gmd.de/usr/schilling	ftp://ftp.fokus.gmd.de/pub/unix





More information about the Gcc mailing list