This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: nano printf + powerpc gcc


On 01/29/2018 05:08 PM, Alexey Neyman wrote:
> Okay, attached is a quick simulation - using a similar code that uses
> va_arg in the caller then either passes a copy of the va_list to a
> callee, or passes it by pointer.

Your simulation isn't testing the same thing as what newlib is doing.
Of course you're going to see garbage.

> 
> #include <stdio.h>
> #include <stdarg.h>
> 
> 
> static void f1(int i,
> #if defined(USE_VA_POINTERS)
> 		va_list *p_ap

This is what newlib is using.  We are taking a va_list * parameter for
the helper function.

> #else
> 		va_list ap

This is irrelevant.  That's not what newlib is doing, so we don't care
how it fails to modify the callee.

> static void f2(va_list ap)
> {
> 	int i, x;
> #if !defined(USE_VA_POINTERS)
> 	va_list ap2;
> 
> 	va_copy(ap2, ap);

This doesn't match what newlib is doing.  We need to perform the va_copy
unconditionally, because we need to take our 'va_list ap' and convert it
into something we can take the address of to pass it to a 'va_list *ap'
f1() function.

> #endif
> 	for (i = 0; i < 10; i++) {
> 		x = va_arg(ap, int);

No, that's not what newlib is doing, either.  You do NOT want to be
mixing ap and ap2 in the same function.

> 		printf("%s#%u: %u\n", __func__, i, x);
> #if defined(USE_VA_POINTERS)
> #if defined(__x86_64__)
> 		f1(i, (va_list *)ap);

EWWWW.  Gross.  NOT at all what newlib is doing.  If USE_VA_POINTERS,
you want platform-independent code that calls

f1(i, &ap2);

and then use ap2 (and ONLY ap2) within the body of f2.

Here's your program, corrected to what newlib should be doing:

#include <stdio.h>
#include <stdarg.h>

static void f1(int i, va_list *p_ap)
{
	double x;
	x = va_arg(*p_ap, double);
	printf("%s#%u: %f\n", __func__, i, x);
}

static void f2(va_list ap)
{
	int i, x;
	va_list ap2;

	va_copy(ap2, ap);
	for (i = 0; i < 10; i++) {
		x = va_arg(ap2, int);
		printf("%s#%u: %u\n", __func__, i, x);
		f1(i, &ap2);
	}
}

void fx(int dummy, ...)
{
	va_list ap;

	va_start(ap, dummy);
	f2(ap);
	va_end(ap);
}

int main(void)
{
	fx(0, 1, 0.1, 2, 0.2, 3, 0.3, 4, 0.4, 5, 0.5, 6, 0.6,
			7, 0.7, 8, 0.8, 9, 0.9, 10, 0.1);
	return 0;
}

which shows NO corruption.
$ ./foo
f2#0: 1
f1#0: 0.100000
f2#1: 2
f1#1: 0.200000
f2#2: 3
f1#2: 0.300000
f2#3: 4
f1#3: 0.400000
f2#4: 5
f1#4: 0.500000
f2#5: 6
f1#5: 0.600000
f2#6: 7
f1#6: 0.700000
f2#7: 8
f1#7: 0.800000
f2#8: 9
f1#8: 0.900000
f2#9: 10
f1#9: 0.100000

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]