Date: Wed, 5 Sep 2001 11:31:15 +0100 (BST) From: Doug Rabson <dfr@nlsystems.com> To: <audit@freebsd.org> Cc: <ia64@freebsd.org> Subject: Making printf work on ia64 Message-ID: <Pine.BSF.4.33.0109051127170.43574-100000@herring.nlsystems.com>
next in thread | raw e-mail | index | archive | help
Since the ia64 architecture has significantly different means for passing arguments than most others, it has an implementation of stdarg.h which doesn't work with our printf. In particular, you cannot take a pointer to the values returned by va_arg(). To get things to work, I had to change printf to copy the arguments instead of pointing to them. I have extensively tested this on ia64 and i386 and can't think of any problems with it. Still, it would be nice to have a few other eyes look over it. The QUAD_MAX part is down to a limitation with my ia64 build environment and should be harmless. Index: vfprintf.c =================================================================== RCS file: /home/ncvs/src/lib/libc/stdio/vfprintf.c,v retrieving revision 1.29 diff -u -r1.29 vfprintf.c --- vfprintf.c 2001/08/20 12:53:34 1.29 +++ vfprintf.c 2001/08/22 09:46:27 @@ -67,14 +67,35 @@ #include "local.h" #include "fvwrite.h" +#ifndef QUAD_MAX +#define QUAD_MAX LONG_MAX +#endif + /* Define FLOATING_POINT to get floating point. */ #define FLOATING_POINT +union arg { + int intarg; + unsigned int uintarg; + long longarg; + unsigned long ulongarg; + quad_t quadarg; + u_quad_t uquadarg; + void *pvoidarg; + char *pchararg; + short *pshortarg; + int *pintarg; + long *plongarg; + quad_t *pquadarg; + double doublearg; + long double longdoublearg; +}; + static int __sprint __P((FILE *, struct __suio *)); static int __sbprintf __P((FILE *, const char *, va_list)) __printflike(2, 0); static char * __ultoa __P((u_long, char *, int, int, char *)); static char * __uqtoa __P((u_quad_t, char *, int, int, char *)); -static void __find_arguments __P((const char *, va_list, void ***)); +static void __find_arguments __P((const char *, va_list, union arg **)); static void __grow_type_table __P((int, unsigned char **, int *)); /* @@ -330,8 +351,8 @@ struct __siov iov[NIOV];/* ... and individual io vectors */ char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ char ox[2]; /* space for 0x hex-prefix */ - void **argtable; /* args, built due to positional arg */ - void *statargtable [STATIC_ARG_TBL_SIZE]; + union arg *argtable; /* args, built due to positional arg */ + union arg statargtable [STATIC_ARG_TBL_SIZE]; int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ @@ -382,7 +403,7 @@ * argument (and arguments must be gotten sequentially). */ #define GETARG(type) \ - ((argtable != NULL) ? *((type*)(argtable[nextarg++])) : \ + ((argtable != NULL) ? *((type*)(&argtable[nextarg++])) : \ (nextarg++, va_arg(ap, type))) /* @@ -912,7 +933,7 @@ * It will be replaces with a malloc-ed one if it overflows. */ static void -__find_arguments (const char *fmt0, va_list ap, void ***argtable) +__find_arguments (const char *fmt0, va_list ap, union arg **argtable) { char *fmt; /* format string */ int ch; /* character from fmt */ @@ -1112,63 +1133,63 @@ * Build the argument table. */ if (tablemax >= STATIC_ARG_TBL_SIZE) { - *argtable = (void **) - malloc (sizeof (void *) * (tablemax + 1)); + *argtable = (union arg *) + malloc (sizeof (union arg) * (tablemax + 1)); } - (*argtable) [0] = NULL; + (*argtable) [0].intarg = 0; for (n = 1; n <= tablemax; n++) { switch (typetable [n]) { case T_UNUSED: - (*argtable) [n] = (void *) &va_arg (ap, int); + (*argtable) [n].intarg = va_arg (ap, int); break; case T_SHORT: - (*argtable) [n] = (void *) &va_arg (ap, int); + (*argtable) [n].intarg = va_arg (ap, int); break; case T_U_SHORT: - (*argtable) [n] = (void *) &va_arg (ap, int); + (*argtable) [n].intarg = va_arg (ap, int); break; case TP_SHORT: - (*argtable) [n] = (void *) &va_arg (ap, short *); + (*argtable) [n].pshortarg = va_arg (ap, short *); break; case T_INT: - (*argtable) [n] = (void *) &va_arg (ap, int); + (*argtable) [n].intarg = va_arg (ap, int); break; case T_U_INT: - (*argtable) [n] = (void *) &va_arg (ap, unsigned int); + (*argtable) [n].uintarg = va_arg (ap, unsigned int); break; case TP_INT: - (*argtable) [n] = (void *) &va_arg (ap, int *); + (*argtable) [n].pintarg = va_arg (ap, int *); break; case T_LONG: - (*argtable) [n] = (void *) &va_arg (ap, long); + (*argtable) [n].longarg = va_arg (ap, long); break; case T_U_LONG: - (*argtable) [n] = (void *) &va_arg (ap, unsigned long); + (*argtable) [n].ulongarg = va_arg (ap, unsigned long); break; case TP_LONG: - (*argtable) [n] = (void *) &va_arg (ap, long *); + (*argtable) [n].plongarg = va_arg (ap, long *); break; case T_QUAD: - (*argtable) [n] = (void *) &va_arg (ap, quad_t); + (*argtable) [n].quadarg = va_arg (ap, quad_t); break; case T_U_QUAD: - (*argtable) [n] = (void *) &va_arg (ap, u_quad_t); + (*argtable) [n].uquadarg = va_arg (ap, u_quad_t); break; case TP_QUAD: - (*argtable) [n] = (void *) &va_arg (ap, quad_t *); + (*argtable) [n].pquadarg = va_arg (ap, quad_t *); break; case T_DOUBLE: - (*argtable) [n] = (void *) &va_arg (ap, double); + (*argtable) [n].doublearg = va_arg (ap, double); break; case T_LONG_DOUBLE: - (*argtable) [n] = (void *) &va_arg (ap, long double); + (*argtable) [n].longdoublearg = va_arg (ap, long double); break; case TP_CHAR: - (*argtable) [n] = (void *) &va_arg (ap, char *); + (*argtable) [n].pchararg = va_arg (ap, char *); break; case TP_VOID: - (*argtable) [n] = (void *) &va_arg (ap, void *); + (*argtable) [n].pvoidarg = va_arg (ap, void *); break; } } -- Doug Rabson Mail: dfr@nlsystems.com Phone: +44 20 8348 6160 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.33.0109051127170.43574-100000>