<p><br>
On Feb 24, 2013 3:50 PM, "Ben Davis" <<a href="mailto:entheh@cantab.net">entheh@cantab.net</a>> wrote:<br>
><br>
> On 24/02/2013 15:13, Ben Davis wrote:<br>
>><br>
>> I'm hitting more problems getting my DLL to start up, but I'll post<br>
>> about those separately later if necessary.<br>
><br>
><br>
> That's weird. Whatever further problem I thought I was hitting, I'm not hitting it any more. I'll put it down to user error on my part. :)<br>
><br>
> Yay! GDC built my DLL and it works!<br>
><br>
> I'll post here a summary of what I had to do, in case it helps anyone else who wants to build a DLL with GDC. Also in case you want to fix the bugs I'm posting a workaround for. I get the feeling you guys are already too busy, but it's here if you want it. :)<br>

></p>
<p>I leave monger to Daniel, and don't really affiliate any modifications to gcc-proper any part if gdc.   However that's not to say that I don't think his work is invaluable. :)<br></p>
<p>> So, to summarise - in order for 32-bit DLLs to work, you need to:<br>
><br>
> - Not use the 20130108 release because of the 32-bit TLS bug;<br>
><br>
> - Replace dll.d and threadaux.d (both in core/sys/windows, containing D-style asm) with versions that contain GCC-style asm instead (my versions below). Because the user's DllMain is responsible for calling down into these, it's easy to declare one's own copies with the fixes applied, and call those instead. I put mine in a subdirectory (does D call those packages?) called 'gdcdll', and then imported them instead of the Windows ones. (They're Boost-licensed so it looks as if this is OK no matter what end-user licence your own code has. I'll put my changes under Boost too; why not? So you guys can use them.)<br>

><br>
> Here are all the specific changes I made for MinGW, along with the old (DMD) versions. You'll find the 'else' parts already in the source.<br>
><br>
> In dll.d somewhere near the top - I think this change already exists somewhere but the only place I found it was in a .di file somewhere:<br>
><br>
> version (MinGW)<br>
> {<br>
>         extern __gshared void* _tls_start;<br>
>         extern __gshared void* _tls_end;<br>
>         extern __gshared void* __xl_a;<br>
><br>
>         alias _tls_start _tlsstart;<br>
>         alias _tls_end _tlsend;<br>
>         alias __xl_a _tls_callbacks_a;<br>
> }<br>
> else<br>
> {<br>
>         extern __gshared void* _tlsstart;<br>
>         extern __gshared void* _tlsend;<br>
>         extern __gshared void* _tls_callbacks_a;<br>
> }<br>
> extern __gshared int   _tls_index;      //This is unchanged<br>
><br>
><br>
> Further down in dll.d:<br>
><br>
> void** peb;<br>
> version (MinGW) {<br>
>         asm<br>
>         {<br>
>                 ".intel_syntax noprefix\n"<br>
>                 "mov EAX,FS:[0x30]\n"<br>
>                 ".att_syntax noprefix\n"<br>
>                 :"=a"(peb);<br>
>         }<br>
> }<br>
> else {<br>
><br>
>         asm<br>
>         {<br>
>                 mov EAX,FS:[0x30];<br>
>                 mov peb, EAX;<br>
>         }<br>
> }<br>
><br>
><br>
> Somewhere in the middle of threadaux.d:<br>
><br>
> version(MinGW)<br>
> {<br>
>         void** teb;<br>
>         asm<br>
>         {<br>
>                 ".intel_syntax noprefix\n"<br>
>                 "mov EAX,FS:[0x18]\n"<br>
>                 "ret\n"<br>
>                 ".att_syntax noprefix\n"<br>
>                 :"=a"(teb);<br>
>         }</p>
<p>I think it's horrible that you use .intel_syntax. \n shouldn't be required either if you just have it as one string.  ;)<br></p>
<p>Regards<br>
-- <br>
Iain Buclaw</p>
<p>*(p < e ? p++ : p) = (c & 0x0f) + '0';<br>
</p>