32 bit vs 64 bit Cygwin, followup

Sam Habiel sam.habiel@gmail.com
Mon Feb 4 14:17:00 GMT 2019


>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
-------------- next part --------------
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.
-------------- next part --------------
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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_sysvabi.c
Type: application/octet-stream
Size: 458 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20190204/40548331/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test_win64abi.c
Type: application/octet-stream
Size: 431 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20190204/40548331/attachment-0001.obj>
-------------- next part --------------

--
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


More information about the Cygwin mailing list