Can GDC make DLLs?

Ben Davis entheh at cantab.net
Sun Feb 24 07:13:23 PST 2013


On 24/02/2013 09:38, Iain Buclaw wrote:
>
> On 23 Feb 2013 22:00, "Ben Davis" <entheh at cantab.net
> <mailto:entheh at cantab.net>> wrote:
>  > I've managed to build my DLL with a replacement for dll.d, using
> GCC-style inline asm for the offending block. Now I've run into another
> problem. This code crashes:
>  >
>  >     static bool tlsCtorRun;
>  >     static this() { tlsCtorRun = true; }
>  > 64841F0F 8B 15 D4 E2 95 64    mov         edx,dword ptr ds:[6495E2D4h]
>  > 64841F15 64 A1 2C 00 00 00    mov         eax,dword ptr fs:[0000002Ch]
>  > 64841F1B 8B 04 90             mov         eax,dword ptr [eax+edx*4]
>  > 64841F1E C6 80 1C 50 96 64 01 mov         byte ptr _tls_start+4
> (6496501Ch)[eax],1     <-- this line crashes
>  > 64841F25 5D                   pop         ebp
>  > 64841F26 C3                   ret
>  >
>  > It works when built with DMD. The code is functionally identical, and
> gets identical values (give or take some randomless with exact memory
> layout), with one exception: the offending line effectively says "byte
> ptr [eax+10h]" instead. So the constant displacement in the instruction
> is 10h instead of 6496501Ch.
>  >
>  > I'm no expert on how DLLs are loaded, but I think I've ruled out any
> load-time code offset adjustment - because I found the exact sequence of
> code bytes in the DLL file on disk, including that number 6496501Ch and
> all the surrounding code mnemonics.
>  >
>  > Is this a compiler TLS codegen bug?
>
> GDC TLS is differrent to whatever DMD uses, so assembly code that works
> for DMD may not necessarily be correct for GDC.

That may be true, but what GDC is generating is wrong nevertheless. 
Otherwise it wouldn't crash! There should be enough evidence here for 
someone to investigate the bug if they want to.

I can also report that the bug only exists in the latest version:
gcc-4.6.1-tdm64-1-gdc-20130108-D2.060.7z - buggy
gcc-4.6.1-tdm64-1-gdc-20121117-D2.060.7z - works
And I suspect it only affects 32-bit code.

With the older build, the codegen looks like this:

     static bool tlsCtorRun;
     static this() { tlsCtorRun = true; }
64841F0F 8B 15 D4 C2 94 64    mov         edx,dword ptr ds:[6494C2D4h]
64841F15 64 A1 2C 00 00 00    mov         eax,dword ptr fs:[0000002Ch]
64841F1B 8B 04 90             mov         eax,dword ptr [eax+edx*4]
64841F1E C6 80 04 00 00 00 01 mov         byte ptr [eax+4],1
64841F25 5D                   pop         ebp
64841F26 C3                   ret

And it doesn't crash.

My DLL needs to be 32-bit - but while I had the broken version 
installed, I also tried a simple hello world exe (Visual D's default) in 
both 32-bit and 64-bit. The 32-bit one crashed somewhere inside the GC 
thread, and the 64-bit one worked. When I switched to the non-broken 
version, they both worked.

I'm hitting more problems getting my DLL to start up, but I'll post 
about those separately later if necessary.

Hope that helps :)


More information about the D.gnu mailing list