Hello,

I'm building the WIC Viewer using Direct2D[1] sample from Microsoft,
converted to C, and I'm getting some strange SIGSERV at the function
ID2D1HwndRenderTarget_GetSize(m_pRT) when the program is compiled with gcc
9.x on a x86_64 system. No problem occurs when compiled with any gcc 8.x
x86_64 or gcc 9.x i686. All builds using MSYS2 toolchain packages.

Looking at the assembly for both builds, I can see there's some difference
in the calling from 8.x to 9.x:

gcc 8.x - works as expected:
   0x0000000000401ef3 <+392>: mov    0x18(%rax),%rax
   0x0000000000401ef7 <+396>: mov    (%rax),%rax
   0x0000000000401efa <+399>: mov    0x1a8(%rax),%rax // rax loaded with
GetSize()
   0x0000000000401f01 <+406>: mov    -0x10(%rbp),%rdx
   0x0000000000401f05 <+410>: mov    0x18(%rdx),%rdx // rdx loaded with
m_pRT
   0x0000000000401f09 <+414>: mov    %rdx,%rcx
   0x0000000000401f0c <+417>: callq  *%rax
   0x0000000000401f0e <+419>: mov    %rax,-0xb0(%rbp)

gcc 9.x - sigserv:
   0x0000000000401f1d <+400>: mov    0x18(%rax),%rax
   0x0000000000401f21 <+404>: mov    (%rax),%rax
   0x0000000000401f24 <+407>: mov    0x1a8(%rax),%rdx // rdx loaded with
GetSize()
   0x0000000000401f2b <+414>: mov    -0x10(%rbp),%rax
   0x0000000000401f2f <+418>: mov    0x18(%rax),%rax // rax loaded with
m_pRT
   0x0000000000401f33 <+422>: mov    %rax,%rcx
   0x0000000000401f36 <+425>: callq  *%rdx
   0x0000000000401f38 <+427>: mov    %rax,-0xb0(%rbp)

The only change I noticed is rax and rdx being swapped, and even though the
call is made correctly, it seems d2d1.dll doesn't like the change:

Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffd41e5dc1a in d2d1!D2D1MakeSkewMatrix () from
C:\Windows\SYSTEM32\d2d1.dll
(gdb) backtrace
#0  0x00007ffd41e5dc1a in d2d1!D2D1MakeSkewMatrix () from
C:\Windows\SYSTEM32\d2d1.dll
#1  0x00007ffd41e4b41d in d2d1!D2D1MakeSkewMatrix () from
C:\Windows\SYSTEM32\d2d1.dll
#2  0x0000000000401f38 in OnPaint (hWnd=0x450ac4) at WicViewerD2D.c:241

>From here, I tried to change the code, simulating the behavior of gcc 8.x,
as follow:

//D2D1_SIZE_F rtSize = ID2D1HwndRenderTarget_GetSize(m_pRT);
D2D1_SIZE_F rtSize;
asm("mov 0x18(%rax),%rax");
asm("mov (%rax),%rax");
asm("mov 0x1a8(%rax),%rax");
asm("mov -0x10(%rbp),%rdx");
asm("mov 0x18(%rdx),%rdx");
asm("mov %rdx,%rcx");
asm("callq *%rax");
asm("mov %rax,-0xb0(%rbp)");

With this change the program worked normally even when compiled with gcc
9.x on x86_64.

I have no idea what to look at from here on, my suspicion is that something
from libd2d1.a isn't working well with gcc 9.x. Does anyone have any idea
what it could be?

Thanks

[1]
https://docs.microsoft.com/en-us/windows/win32/wic/-wic-sample-d2d-viewer

_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to