>That's not GCC fault. You're running varargs, written for the standard >stack layout of the MSABI target from a function with a stack laid out >in SYSV ABI. That can't work.
I did some research to see how to write my own version of varargs (the code base is already instrumented to do different versions of varargs based on operating system). What I noticed though is that after disassembling code for win64 abi vs sysv abi, it seems like gcc/crt is attempting to do the right thing. There is different code for sysv vs win64 for va_start. sysv: 10 va_list vl; 11 va_start(vl,n); 0x00000001004010e4 <+100>: movl $0x8,-0xc8(%rbp) 0x00000001004010ee <+110>: movl $0x30,-0xc4(%rbp) 0x00000001004010f8 <+120>: lea 0x10(%rbp),%rax 0x00000001004010fc <+124>: mov %rax,-0xc0(%rbp) 0x0000000100401103 <+131>: lea -0xb0(%rbp),%rax 0x000000010040110a <+138>: mov %rax,-0xb8(%rbp) win64: 10 va_list vl; 11 va_start(vl,n); 0x00000001004010a3 <+35>: lea 0x18(%rbp),%rax 0x00000001004010a7 <+39>: mov %rax,-0x18(%rbp) So there may be a incomplete support for varargs for the sysv abi--but buggy. I attached the disassembly as well as the testing programs for your convenience. --Sam
Dump of assembler code for function PrintFloats: test_sysvabi.c: 6 { 0x0000000100401080 <+0>: push %rbp 0x0000000100401081 <+1>: mov %rsp,%rbp 0x0000000100401084 <+4>: sub $0x100,%rsp 0x000000010040108b <+11>: mov %edi,-0xd4(%rbp) 0x0000000100401091 <+17>: mov %rsi,-0xa8(%rbp) 0x0000000100401098 <+24>: mov %rdx,-0xa0(%rbp) 0x000000010040109f <+31>: mov %rcx,-0x98(%rbp) 0x00000001004010a6 <+38>: mov %r8,-0x90(%rbp) 0x00000001004010ad <+45>: mov %r9,-0x88(%rbp) 0x00000001004010b4 <+52>: test %al,%al 0x00000001004010b6 <+54>: je 0x1004010d8 <PrintFloats+88> 0x00000001004010b8 <+56>: movaps %xmm0,-0x80(%rbp) 0x00000001004010bc <+60>: movaps %xmm1,-0x70(%rbp) 0x00000001004010c0 <+64>: movaps %xmm2,-0x60(%rbp) 0x00000001004010c4 <+68>: movaps %xmm3,-0x50(%rbp) 0x00000001004010c8 <+72>: movaps %xmm4,-0x40(%rbp) 0x00000001004010cc <+76>: movaps %xmm5,-0x30(%rbp) 0x00000001004010d0 <+80>: movaps %xmm6,-0x20(%rbp) 0x00000001004010d4 <+84>: movaps %xmm7,-0x10(%rbp) 7 int i; 8 double val; 9 printf ("Printing floats:"); 0x00000001004010d8 <+88>: lea 0x1f21(%rip),%rcx # 0x100403000 0x00000001004010df <+95>: callq 0x100401270 <printf> 10 va_list vl; 11 va_start(vl,n); 0x00000001004010e4 <+100>: movl $0x8,-0xc8(%rbp) 0x00000001004010ee <+110>: movl $0x30,-0xc4(%rbp) 0x00000001004010f8 <+120>: lea 0x10(%rbp),%rax 0x00000001004010fc <+124>: mov %rax,-0xc0(%rbp) 0x0000000100401103 <+131>: lea -0xb0(%rbp),%rax 0x000000010040110a <+138>: mov %rax,-0xb8(%rbp) 12 for (i=0;i<n;i++) 0x0000000100401111 <+145>: movl $0x0,-0xb4(%rbp) 0x000000010040111b <+155>: jmp 0x100401163 <PrintFloats+227> 13 { 14 val=va_arg(vl,double); 0x000000010040111d <+157>: mov -0xc8(%rbp),%rax 0x0000000100401124 <+164>: lea 0x8(%rax),%rdx 0x0000000100401128 <+168>: mov %rdx,-0xc8(%rbp) 0x000000010040112f <+175>: movsd (%rax),%xmm0 0x0000000100401133 <+179>: movsd %xmm0,-0xc0(%rbp) 15 printf (" [%.2f]",val); 0x000000010040113b <+187>: movsd -0xc0(%rbp),%xmm1 0x0000000100401143 <+195>: movsd -0xc0(%rbp),%xmm0 0x000000010040114b <+203>: movq %xmm0,%rdx 0x0000000100401150 <+208>: lea 0x1eba(%rip),%rcx # 0x100403011 0x0000000100401157 <+215>: callq 0x100401270 <printf> 12 for (i=0;i<n;i++) 0x000000010040115c <+220>: addl $0x1,-0xb4(%rbp) 0x0000000100401163 <+227>: mov -0xb4(%rbp),%eax 0x0000000100401169 <+233>: cmp -0xd4(%rbp),%eax 0x000000010040116f <+239>: jl 0x10040111d <PrintFloats+157> 16 } 17 va_end(vl); 18 printf ("\n"); 0x0000000100401171 <+241>: mov $0xa,%ecx 0x0000000100401176 <+246>: callq 0x100401280 <putchar> 19 } 0x000000010040117b <+251>: nop 0x000000010040117c <+252>: leaveq 0x000000010040117d <+253>: retq End of assembler dump.
Dump of assembler code for function PrintFloats: test_win64abi.c: 6 { 0x0000000100401080 <+0>: push %rbp 0x0000000100401081 <+1>: mov %rsp,%rbp 0x0000000100401084 <+4>: sub $0x40,%rsp 0x0000000100401088 <+8>: mov %ecx,0x10(%rbp) 0x000000010040108b <+11>: mov %rdx,0x18(%rbp) 0x000000010040108f <+15>: mov %r8,0x20(%rbp) 0x0000000100401093 <+19>: mov %r9,0x28(%rbp) 7 int i; 8 double val; 9 printf ("Printing floats:"); 0x0000000100401097 <+23>: lea 0x1f62(%rip),%rcx # 0x100403000 0x000000010040109e <+30>: callq 0x1004011a0 <printf> 10 va_list vl; 11 va_start(vl,n); 0x00000001004010a3 <+35>: lea 0x18(%rbp),%rax 0x00000001004010a7 <+39>: mov %rax,-0x18(%rbp) 12 for (i=0;i<n;i++) 0x00000001004010ab <+43>: movl $0x0,-0x4(%rbp) 0x00000001004010b2 <+50>: jmp 0x1004010e8 <PrintFloats+104> 13 { 14 val=va_arg(vl,double); 0x00000001004010b4 <+52>: mov -0x18(%rbp),%rax 0x00000001004010b8 <+56>: lea 0x8(%rax),%rdx 0x00000001004010bc <+60>: mov %rdx,-0x18(%rbp) 0x00000001004010c0 <+64>: movsd (%rax),%xmm0 0x00000001004010c4 <+68>: movsd %xmm0,-0x10(%rbp) 15 printf (" [%.2f]",val); 0x00000001004010c9 <+73>: movsd -0x10(%rbp),%xmm1 0x00000001004010ce <+78>: movsd -0x10(%rbp),%xmm0 0x00000001004010d3 <+83>: movq %xmm0,%rdx 0x00000001004010d8 <+88>: lea 0x1f32(%rip),%rcx # 0x100403011 0x00000001004010df <+95>: callq 0x1004011a0 <printf> 12 for (i=0;i<n;i++) 0x00000001004010e4 <+100>: addl $0x1,-0x4(%rbp) 0x00000001004010e8 <+104>: mov -0x4(%rbp),%eax 0x00000001004010eb <+107>: cmp 0x10(%rbp),%eax 0x00000001004010ee <+110>: jl 0x1004010b4 <PrintFloats+52> 16 } 17 va_end(vl); 18 printf ("\n"); 0x00000001004010f0 <+112>: mov $0xa,%ecx 0x00000001004010f5 <+117>: callq 0x1004011b0 <putchar> 19 } 0x00000001004010fa <+122>: nop 0x00000001004010fb <+123>: add $0x40,%rsp 0x00000001004010ff <+127>: pop %rbp 0x0000000100401100 <+128>: retq End of assembler dump.
test_sysvabi.c
Description: Binary data
test_win64abi.c
Description: Binary data
-- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple