~nabijaczleweli/ossp#70: 
[l2 0.9.11] "incorrect" usage of va_list objects causes segfault on amd64

#Upstream Ticket 70 from 2005-10-13 10:28:44

va_list objects has different internals on i386 and amd64. See the attachment.

Status
REPORTED
Submitter
~nabijaczleweli
Assigned to
No-one
Submitted
4 months ago
Updated
4 months ago
Labels
CVSTrac l2

~nabijaczleweli 4 months ago

#Attached l2ticket on 2005-10-13 10:29:48 (part 1/2)

l2 library seems to be written with the assumption that the following
program prints "bb" to stdout:

--- tmp.c begins here ---
#include <stdarg.h>
#include <stdio.h>

void
g(va_list *ap)
{
	printf("%s\n", va_arg(*ap, char *));
}

void
ff(va_list ap)
{
	g(&ap);
}

void
f(const char *p1, ...)
{
	va_list	ap;
	va_start(ap, p1);
	ff(ap);
	va_end(ap);
}

int
main(int argc, char **argv)
{
	f("aa", "bb", "cc");
	return 0;
}

/* EOF */
--- tmp.c ends here ---

Well, it does not on the following machine:

# uname -a
FreeBSD qlovarnika.bg.datamax 6.0-RC1 FreeBSD 6.0-RC1 #0: Mon Oct 10 17:41:04 EEST 2005     root@qlovarnika.bg.datamax:/usr/obj/usr/src/sys/QLOVARNIKA  amd64

# gcc -v
Using built-in specs.
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 3.4.4 [FreeBSD] 20050518

What happens:

# gcc -g tmp.c -o tmp
tmp.c: In function `ff':
tmp.c:13: warning: passing arg 1 of `g' from incompatible pointer type

# ./tmp
P���
Illegal instruction: 4 (core dumped)

Why:

# gdb ./tmp
(gdb) b 21
Breakpoint 1 at 0x40083a: file tmp.c, line 21.

(gdb) r
Breakpoint 1, f (p1=0x400916 "aa") at tmp.c:21
21		ff(ap);

(gdb) ins &ap
$1 = (va_list *) 0x7fffffffe940
(gdb) ins ap
$2 = {{gp_offset = 8, fp_offset = 48, overflow_arg_area = 0x7fffffffea30, 
    reg_save_area = 0x7fffffffe970}}

(gdb) s
ff (ap=0x7fffffffe940) at tmp.c:13
13		g(&ap);

// ap has turned itself into a pointer

(gdb) ins &ap
$3 = (struct __va_list_tag **) 0x7fffffffe918
(gdb) ins ap
$4 = (struct __va_list_tag *) 0x7fffffffe940
(gdb) ins *ap
$5 = {gp_offset = 8, fp_offset = 48, overflow_arg_area = 0x7fffffffea30, 
  reg_save_area = 0x7fffffffe970}

(gdb) s
g (ap=0x7fffffffe918) at tmp.c:7
7		printf("%s\n", va_arg(*ap, char *));

(gdb) ins &ap
$6 = (va_list **) 0x7fffffffe8f8
(gdb) ins ap
$7 = (va_list *) 0x7fffffffe918
(gdb) ins *ap
$8 = {{gp_offset = 4294961472, fp_offset = 32767, 
    overflow_arg_area = 0x7fffffffea20, reg_save_area = 0x400846}}
(gdb) ins **(va_list**)ap
$9 = {{gp_offset = 8, fp_offset = 48, overflow_arg_area = 0x7fffffffea30, 
    reg_save_area = 0x7fffffffe970}}
(gdb) q

Conclusion (based on some more tests and debugging):
* Using va_list types of parameters does different things on i386 and
  amd64: on i386 a copy of the object is passed and modification in
  subroutines has no effect in the calling routine, while on amd64 it
  is transparently converted into a pointer (va_arg() manages to work
  with it) and modification is visible to the calling routines.
* Passing va_list* object from the routine that has declared it (and
  called va_start()) does the same thing on i386 and amd64, e.g.:
  the following prog prints bb cc on both i386 and amd64:

--- tmp1.c begins here ---
#include <stdarg.h>
#include <stdio.h>

void
g(va_list *ap)
{
	printf("%s\n", va_arg(*ap, char *));
}

void
ff(va_list *ap)
{
	g(ap);
}

void
f(const char *p1, ...)
{
	va_list	ap;
	va_start(ap, p1);
	ff(&ap);
	ff(&ap);
	va_end(ap);
}

int
main(int argc, char **argv)
{
	f("aa", "bb", "cc");
	return 0;
}

/* EOF */
--- tmp1.c ends here ---

Solution?

The patch below is based on the assumption that the above tmp1.c
prints bb cc to stdout, this may or may not be true for some other
architecture/compiler/os.

I have tested it on:
FreeBSD qlovarnika.bg.datamax 6.0-RC1 FreeBSD 6.0-RC1 #0: Mon Oct 10 17:41:04 EEST 2005     root@qlovarnika.bg.datamax:/usr/obj/usr/src/sys/QLOVARNIKA  amd64
Using built-in specs.
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 3.4.4 [FreeBSD] 20050518

FreeBSD zybyt.bg.datamax 6.0-RC1 FreeBSD 6.0-RC1 #0: Sun Sep 11 16:39:23 EEST 2005     root@zybyt.bg.datamax:/usr/obj/usr/src/sys/ZYBYT  i386
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.4.4 [FreeBSD] 20050518

Linux hostname 2.4.18-14 <a href="/~nabijaczleweli/ossp/1" title="~nabijaczleweli/ossp#1: (Ticket number 1 unused on CVSTrac)">#1</a> Wed Sep 4 13:35:50 EDT 2002 i686 i686 i386 GNU/Linux
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --host=i386-redhat-linux --with-system-zlib --enable-__cxa_atexit
Thread model: posix
gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7)

Overview of the patch:
All the routines that have va_list arguments take va_list*.
The routines that craft va_list structures (with va_start()) pass
them with &ap to all subroutines (except va_arg() and va_end() ofcourse)
they use.
Caveat: if we need to pass a copy of va_list object, e.g. we need it
unmodified after the subroutine returns, we have to use va_copy().

Please review carefully!

--- l2_va.diff begins here ---
diff -ur --exclude-from=excl l2-0.9.11.orig/l2.h.in l2-0.9.11/l2.h.in
--- l2-0.9.11.orig/l2.h.in	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2.h.in	Thu Oct 13 08:20:19 2005
@@ -168,7 +168,7 @@
     const char *name;
     l2_chtype_t type;
     l2_result_t (*create)   (l2_context_t *ctx, l2_channel_t *ch);
-    l2_result_t (*configure)(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap);
+    l2_result_t (*configure)(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap);
     l2_result_t (*open)     (l2_context_t *ctx, l2_channel_t *ch);
     l2_result_t (*write)    (l2_context_t *ctx, l2_channel_t *ch, l2_level_t level, const char *buf, size_t bufsize);
     l2_result_t (*flush)    (l2_context_t *ctx, l2_channel_t *ch);
@@ -222,7 +222,7 @@
 l2_result_t   l2_channel_flush      (l2_channel_t *ch);
 l2_result_t   l2_channel_close      (l2_channel_t *ch);
 l2_result_t   l2_channel_log        (l2_channel_t *ch, l2_level_t level, const char *fmt, ...);
-l2_result_t   l2_channel_vlog       (l2_channel_t *ch, l2_level_t level, const char *fmt, va_list ap);
+l2_result_t   l2_channel_vlog       (l2_channel_t *ch, l2_level_t level, const char *fmt, va_list *ap);
 l2_result_t   l2_channel_link       (l2_channel_t *ch, l2_link_t id, l2_channel_t *ch2, ...);
 l2_result_t   l2_channel_unlink     (l2_channel_t *ch);
 l2_result_t   l2_channel_upstream   (l2_channel_t *ch, l2_channel_t **chU);
@@ -232,10 +232,10 @@
 
 /* channel tree specification operations */
 l2_result_t   l2_spec               (l2_channel_t **ch, l2_env_t *env, const char *spec, ...);
-l2_result_t   l2_vspec              (l2_channel_t **ch, l2_env_t *env, const char *spec, va_list ap);
+l2_result_t   l2_vspec              (l2_channel_t **ch, l2_env_t *env, const char *spec, va_list *ap);
 
 /* utility operations */
-l2_result_t   l2_util_setparams     (l2_env_t *env, l2_param_t p[], const char *fmt, va_list ap);
+l2_result_t   l2_util_setparams     (l2_env_t *env, l2_param_t p[], const char *fmt, va_list *ap);
 l2_result_t   l2_util_l2s           (char *string,       size_t maxlen, int sep, unsigned int  levelmask);
 l2_result_t   l2_util_s2l           (const char *string, size_t maxlen, int sep, unsigned int *levelmask);
 l2_result_t   l2_util_fmt_string    (l2_context_t *, const char, const char *, char *, size_t, size_t *, va_list *);
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_buffer.c l2-0.9.11/l2_ch_buffer.c
--- l2-0.9.11.orig/l2_ch_buffer.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_buffer.c	Thu Oct 13 08:14:59 2005
@@ -156,7 +156,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_buffer_t *cfg = (l2_ch_buffer_t *)ctx->vp;
     l2_param_t pa[4];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_fd.c l2-0.9.11/l2_ch_fd.c
--- l2-0.9.11.orig/l2_ch_fd.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_fd.c	Thu Oct 13 08:10:28 2005
@@ -55,7 +55,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_fd_t *cfg;
     l2_param_t pa[2];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_file.c l2-0.9.11/l2_ch_file.c
--- l2-0.9.11.orig/l2_ch_file.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_file.c	Thu Oct 13 08:12:12 2005
@@ -115,7 +115,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_file_t *cfg = (l2_ch_file_t *)ctx->vp;
     l2_param_t pa[7];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_filter.c l2-0.9.11/l2_ch_filter.c
--- l2-0.9.11.orig/l2_ch_filter.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_filter.c	Thu Oct 13 08:14:22 2005
@@ -63,7 +63,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_filter_t *cfg = (l2_ch_filter_t *)ctx->vp;
     l2_env_t *env;
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_irc.c l2-0.9.11/l2_ch_irc.c
--- l2-0.9.11.orig/l2_ch_irc.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_irc.c	Thu Oct 13 08:13:30 2005
@@ -95,7 +95,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_irc_t *cfg = (l2_ch_irc_t *)ctx->vp;
     l2_param_t pa[12];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_pipe.c l2-0.9.11/l2_ch_pipe.c
--- l2-0.9.11.orig/l2_ch_pipe.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_pipe.c	Thu Oct 13 08:12:31 2005
@@ -170,7 +170,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_pipe_t *cfg = (l2_ch_pipe_t *)ctx->vp;
     l2_param_t pa[4];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_prefix.c l2-0.9.11/l2_ch_prefix.c
--- l2-0.9.11.orig/l2_ch_prefix.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_prefix.c	Thu Oct 13 08:14:30 2005
@@ -62,7 +62,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_prefix_t *cfg = (l2_ch_prefix_t *)ctx->vp;
     l2_param_t pa[3];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_smtp.c l2-0.9.11/l2_ch_smtp.c
--- l2-0.9.11.orig/l2_ch_smtp.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_smtp.c	Thu Oct 13 08:13:48 2005
@@ -89,7 +89,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_smtp_t *cfg = (l2_ch_smtp_t *)ctx->vp;
     l2_param_t pa[10];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_socket.c l2-0.9.11/l2_ch_socket.c
--- l2-0.9.11.orig/l2_ch_socket.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_socket.c	Thu Oct 13 08:13:11 2005
@@ -73,7 +73,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_socket_t *cfg = (l2_ch_socket_t *)ctx->vp;
     l2_param_t pa[5];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ch_syslog.c l2-0.9.11/l2_ch_syslog.c
--- l2-0.9.11.orig/l2_ch_syslog.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ch_syslog.c	Thu Oct 13 08:12:54 2005
@@ -157,7 +157,7 @@
 }
 
 /* configure channel */
-static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
+static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list *ap)
 {
     l2_ch_syslog_t *cfg = (l2_ch_syslog_t *)ctx->vp;
     l2_param_t pa[8];
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_channel.c l2-0.9.11/l2_channel.c
--- l2-0.9.11.orig/l2_channel.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_channel.c	Thu Oct 13 08:15:46 2005
@@ -284,7 +284,7 @@
     rv = L2_OK;
     va_start(ap, fmt);
     if (ch->handler.configure != NULL)
-        rv = ch->handler.configure(&ch->context, ch, fmt, ap);
+        rv = ch->handler.configure(&ch->context, ch, fmt, &ap);
     va_end(ap);
 
     return rv;
@@ -506,7 +506,7 @@
 
     /* pass-through to va_list-based variant */
     va_start(ap, fmt);
-    rv = l2_channel_vlog(ch, level, fmt, ap);
+    rv = l2_channel_vlog(ch, level, fmt, &ap);
     va_end(ap);
 
     return rv;
@@ -551,7 +551,7 @@
 }
 
 /* log a message to channel (va_list-variant) */
-l2_result_t l2_channel_vlog(l2_channel_t *ch, l2_level_t level, const char *fmt, va_list ap)
+l2_result_t l2_channel_vlog(l2_channel_t *ch, l2_level_t level, const char *fmt, va_list *ap)
 {
     int l, j;
     size_t len;
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_env.c l2-0.9.11/l2_env.c
--- l2-0.9.11.orig/l2_env.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_env.c	Thu Oct 13 07:52:59 2005
@@ -159,7 +159,7 @@
 
     /* remember error information */
     va_start(ap, fmt);
-    l2_util_vsprintf(env->szErrorInfo, sizeof(env->szErrorInfo), fmt, ap);
+    l2_util_vsprintf(env->szErrorInfo, sizeof(env->szErrorInfo), fmt, &ap);
     env->rvErrorInfo = rv;
     va_end(ap);
 
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_spec.c l2-0.9.11/l2_spec.c
--- l2-0.9.11.orig/l2_spec.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_spec.c	Thu Oct 13 08:09:33 2005
@@ -48,14 +48,14 @@
 
     /* pass-through to va_list-based variant */
     va_start(ap, spec);
-    rv = l2_vspec(ch, env, spec, ap);
+    rv = l2_vspec(ch, env, spec, &ap);
     va_end(ap);
 
     return rv;
 }
 
 /* build a channel tree according to a textual specification (va_list variant) */
-l2_result_t l2_vspec(l2_channel_t **ch, l2_env_t *env, const char *spec, va_list ap)
+l2_result_t l2_vspec(l2_channel_t **ch, l2_env_t *env, const char *spec, va_list *ap)
 {
     l2_spec_ctx_t ctx;
     void *yyscan;
@@ -146,7 +146,7 @@
 
     /* remember error */
     va_start(ap, fmt);
-    if ((cp = l2_util_vasprintf(fmt, ap)) != NULL) {
+    if ((cp = l2_util_vasprintf(fmt, &ap)) != NULL) {
         l2_env_errorinfo(ctx->env, rv, "line %d, column %d: `%s'; %s",
                          line, column, cpBuf, cp);
         free(cp);
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ut_format.c l2-0.9.11/l2_ut_format.c
--- l2-0.9.11.orig/l2_ut_format.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ut_format.c	Wed Oct 12 20:46:08 2005
@@ -640,7 +640,7 @@
 l2_util_format(
     l2_util_format_t *vbuff,
     const char *fmt,
-    va_list ap)
+    va_list *ap)
 {
     register char *sp;
     register char *bep;
@@ -735,7 +735,7 @@
                     adjust_width = TRUE;
                 }
                 else if (*fmt == '*') {
-                    min_width = va_arg(ap, int);
+                    min_width = va_arg(*ap, int);
                     fmt++;
                     adjust_width = TRUE;

~nabijaczleweli 4 months ago

#Attached l2ticket on 2005-10-13 10:29:48 (part 2/2)

                     if (min_width < 0) {
@@ -760,7 +760,7 @@
                         STR_TO_DEC(fmt, precision);
                     }
                     else if (*fmt == '*') {
-                        precision = va_arg(ap, int);
+                        precision = va_arg(*ap, int);
                         fmt++;
                         if (precision < 0)
                             precision = 0;
@@ -809,17 +809,17 @@
                 /* Unsigned Decimal Integer */
                 case 'u':
                     if (var_type == IS_QUAD) {
-                        i_quad = va_arg(ap, u_quad_int);
+                        i_quad = va_arg(*ap, u_quad_int);
                         s = conv_10_quad(i_quad, 1, &is_negative,
                                          &num_buf[NUM_BUF_SIZE], &s_len);
                     }
                     else {
                         if (var_type == IS_LONG)
-                            i_num = (long_int)va_arg(ap, u_long_int);
+                            i_num = (long_int)va_arg(*ap, u_long_int);
                         else if (var_type == IS_SHORT)
-                            i_num = (long_int)(unsigned short)va_arg(ap, unsigned int);
+                            i_num = (long_int)(unsigned short)va_arg(*ap, unsigned int);
                         else
-                            i_num = (long_int)va_arg(ap, unsigned int);
+                            i_num = (long_int)va_arg(*ap, unsigned int);
                         s = conv_10(i_num, 1, &is_negative,
                                     &num_buf[NUM_BUF_SIZE], &s_len);
                     }
@@ -830,17 +830,17 @@
                 case 'd':
                 case 'i':
                     if (var_type == IS_QUAD) {
-                        i_quad = va_arg(ap, quad_int);
+                        i_quad = va_arg(*ap, quad_int);
                         s = conv_10_quad(i_quad, 0, &is_negative,
                                          &num_buf[NUM_BUF_SIZE], &s_len);
                     }
                     else {
                         if (var_type == IS_LONG)
-                            i_num = (long_int)va_arg(ap, long_int);
+                            i_num = (long_int)va_arg(*ap, long_int);
                         else if (var_type == IS_SHORT)
-                            i_num = (long_int)(short)va_arg(ap, int);
+                            i_num = (long_int)(short)va_arg(*ap, int);
                         else
-                            i_num = (long_int)va_arg(ap, int);
+                            i_num = (long_int)va_arg(*ap, int);
                         s = conv_10(i_num, 0, &is_negative,
                                     &num_buf[NUM_BUF_SIZE], &s_len);
                     }
@@ -857,17 +857,17 @@
                 /* Unsigned Octal Integer */
                 case 'o':
                     if (var_type == IS_QUAD) {
-                        ui_quad = va_arg(ap, u_quad_int);
+                        ui_quad = va_arg(*ap, u_quad_int);
                         s = conv_p2_quad(ui_quad, 3, *fmt,
                                          &num_buf[NUM_BUF_SIZE], &s_len);
                     }
                     else {
                         if (var_type == IS_LONG)
-                            ui_num = (u_long_int) va_arg(ap, u_long_int);
+                            ui_num = (u_long_int) va_arg(*ap, u_long_int);
                         else if (var_type == IS_SHORT)
-                            ui_num = (u_long_int)(unsigned short)va_arg(ap, unsigned int);
+                            ui_num = (u_long_int)(unsigned short)va_arg(*ap, unsigned int);
                         else
-                            ui_num = (u_long_int)va_arg(ap, unsigned int);
+                            ui_num = (u_long_int)va_arg(*ap, unsigned int);
                         s = conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len);
                     }
                     FIX_PRECISION(adjust_precision, precision, s, s_len);
@@ -881,17 +881,17 @@
                 case 'x':
                 case 'X':
                     if (var_type == IS_QUAD) {
-                        ui_quad = va_arg(ap, u_quad_int);
+                        ui_quad = va_arg(*ap, u_quad_int);
                         s = conv_p2_quad(ui_quad, 4, *fmt,
                                          &num_buf[NUM_BUF_SIZE], &s_len);
                     }
                     else {
                         if (var_type == IS_LONG)
-                            ui_num = (u_long_int)va_arg(ap, u_long_int);
+                            ui_num = (u_long_int)va_arg(*ap, u_long_int);
                         else if (var_type == IS_SHORT)
-                            ui_num = (u_long_int)(unsigned short)va_arg(ap, unsigned int);
+                            ui_num = (u_long_int)(unsigned short)va_arg(*ap, unsigned int);
                         else
-                            ui_num = (u_long_int)va_arg(ap, unsigned int);
+                            ui_num = (u_long_int)va_arg(*ap, unsigned int);
                         s = conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len);
                     }
                     FIX_PRECISION(adjust_precision, precision, s, s_len);
@@ -904,7 +904,7 @@
 
                 /* String */
                 case 's':
-                    s = va_arg(ap, char *);
+                    s = va_arg(*ap, char *);
                     if (s != NULL) {
                         s_len = strlen(s);
                         if (adjust_precision && precision < s_len)
@@ -921,7 +921,7 @@
                 case 'f':
                 case 'e':
                 case 'E':
-                    fp_num = va_arg(ap, double);
+                    fp_num = va_arg(*ap, double);
                     if (isnan(fp_num)) {
                         s = "NaN";
                         s_len = 3;
@@ -947,7 +947,7 @@
                 /* Double Floating Point (style 2) */
                 case 'g':
                 case 'G':
-                    fp_num = va_arg(ap, double);
+                    fp_num = va_arg(*ap, double);
                     if (isnan(fp_num)) {
                         s = "NaN";
                         s_len = 3;
@@ -981,7 +981,7 @@
 
                 /* Single Character */
                 case 'c':
-                    char_buf[0] = (char) (va_arg(ap, int));
+                    char_buf[0] = (char) (va_arg(*ap, int));
                     s = &char_buf[0];
                     s_len = 1;
                     pad_char = ' ';
@@ -998,13 +998,13 @@
                 /* Special: Number of already written characters */
                 case 'n':
                     if (var_type == IS_QUAD)
-                        *(va_arg(ap, quad_int *)) = cc;
+                        *(va_arg(*ap, quad_int *)) = cc;
                     else if (var_type == IS_LONG)
-                        *(va_arg(ap, long *)) = cc;
+                        *(va_arg(*ap, long *)) = cc;
                     else if (var_type == IS_SHORT)
-                        *(va_arg(ap, short *)) = cc;
+                        *(va_arg(*ap, short *)) = cc;
                     else
-                        *(va_arg(ap, int *)) = cc;
+                        *(va_arg(*ap, int *)) = cc;
                     break;
 
                 /*
@@ -1012,10 +1012,10 @@
                  */
                 case 'p':
 #if defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == SIZEOF_VOID_P)
-                    ui_quad = (u_quad_int) va_arg(ap, void *);
+                    ui_quad = (u_quad_int) va_arg(*ap, void *);
                     s = conv_p2_quad(ui_quad, 4, 'x', &num_buf[NUM_BUF_SIZE], &s_len);
 #else
-                    ui_num = (u_long_int) va_arg(ap, void *);
+                    ui_num = (u_long_int) va_arg(*ap, void *);
                     s = conv_p2(ui_num, 4, 'x', &num_buf[NUM_BUF_SIZE], &s_len);
 #endif
                     pad_char = ' ';
@@ -1043,7 +1043,7 @@
                     if (vbuff->format != NULL) {
                         vbuff->format(vbuff,
                                       &prefix_char, &pad_char, &s, &s_len,
-                                      num_buf, NUM_BUF_SIZE, extinfo, *fmt, (va_list *)(void *)&ap);
+                                      num_buf, NUM_BUF_SIZE, extinfo, *fmt, ap);
                         if (s == NULL)
                             return -1;
                     }
@@ -1112,7 +1112,7 @@
     return -1;
 }
 
-int l2_util_vsprintf(char *s, size_t n, const char *fmt, va_list ap)
+int l2_util_vsprintf(char *s, size_t n, const char *fmt, va_list *ap)
 {
     l2_util_format_t handle;
     char buf[STR_FORMAT_BUFLEN];
@@ -1147,18 +1147,18 @@
     return rv;
 }
 
-char *l2_util_vasprintf(const char *fmt, va_list ap)
+char *l2_util_vasprintf(const char *fmt, va_list *ap)
 {
     va_list apbak;
     char *s;
     int rv;
 
-    va_copy(apbak, ap);
+    va_copy(apbak, *ap);
     if ((rv = l2_util_vsprintf(NULL, -1, fmt, ap)) == -1)
         return NULL;
     if ((s = malloc(rv+1)) == NULL)
         return NULL;
-    va_copy(ap, apbak);
+    va_copy(*ap, apbak);
     if ((rv = l2_util_vsprintf(s, rv+1, fmt, ap)) == -1) {
         free(s);
         return NULL;
@@ -1172,7 +1172,7 @@
     int rv;
 
     va_start(ap, fmt);
-    rv = l2_util_vsprintf(s, n, fmt, ap);
+    rv = l2_util_vsprintf(s, n, fmt, &ap);
     va_end(ap);
     return rv;
 }
@@ -1183,7 +1183,7 @@
     char *rv;
 
     va_start(ap, fmt);
-    rv = l2_util_vasprintf(fmt, ap);
+    rv = l2_util_vasprintf(fmt, &ap);
     va_end(ap);
     return rv;
 }
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ut_format.h l2-0.9.11/l2_ut_format.h
--- l2-0.9.11.orig/l2_ut_format.h	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ut_format.h	Wed Oct 12 20:45:22 2005
@@ -66,9 +66,9 @@
 
 typedef struct l2_util_format_st l2_util_format_t;
 
-int   l2_util_format    (l2_util_format_t *vbuff, const char *fmt, va_list ap);
-int   l2_util_vsprintf  (char *s, size_t n, const char *fmt, va_list ap);
-char *l2_util_vasprintf (const char *fmt, va_list ap);
+int   l2_util_format    (l2_util_format_t *vbuff, const char *fmt, va_list *ap);
+int   l2_util_vsprintf  (char *s, size_t n, const char *fmt, va_list *ap);
+char *l2_util_vasprintf (const char *fmt, va_list *ap);
 int   l2_util_sprintf   (char *s, size_t n, const char *fmt, ...);
 char *l2_util_asprintf  (const char *fmt, ...);
 
diff -ur --exclude-from=excl l2-0.9.11.orig/l2_ut_param.c l2-0.9.11/l2_ut_param.c
--- l2-0.9.11.orig/l2_ut_param.c	Mon Oct  3 11:06:18 2005
+++ l2-0.9.11/l2_ut_param.c	Thu Oct 13 08:06:33 2005
@@ -37,7 +37,7 @@
 #include <math.h>
 #include <ctype.h>
 
-l2_result_t l2_util_setparams(l2_env_t *env, l2_param_t pa[], const char *fmt, va_list ap)
+l2_result_t l2_util_setparams(l2_env_t *env, l2_param_t pa[], const char *fmt, va_list *ap)
 {
     char *cpB, *cpE;
     char *spec;
--- l2_va.diff ends here ---

Register here or Log in to comment, or comment via email.