Skip site navigation (1)Skip section navigation (2)
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>