Can GDC make DLLs?

Ben Davis entheh at cantab.net
Sun Feb 24 07:46:09 PST 2013


On 24/02/2013 15:13, Ben Davis wrote:
> I'm hitting more problems getting my DLL to start up, but I'll post
> about those separately later if necessary.

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. :)

Yay! GDC built my DLL and it works!

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. :)

So, to summarise - in order for 32-bit DLLs to work, you need to:

- Not use the 20130108 release because of the 32-bit TLS bug;

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

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.

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:

version (MinGW)
{
	extern __gshared void* _tls_start;
	extern __gshared void* _tls_end;
	extern __gshared void* __xl_a;

	alias _tls_start _tlsstart;
	alias _tls_end _tlsend;
	alias __xl_a _tls_callbacks_a;
}
else
{
	extern __gshared void* _tlsstart;
	extern __gshared void* _tlsend;
	extern __gshared void* _tls_callbacks_a;
}
extern __gshared int   _tls_index;	//This is unchanged


Further down in dll.d:

void** peb;
version (MinGW) {
	asm
	{
		".intel_syntax noprefix\n"
		"mov EAX,FS:[0x30]\n"
		".att_syntax noprefix\n"
		:"=a"(peb);
	}
}
else {
	asm
	{
		mov EAX,FS:[0x30];
		mov peb, EAX;
	}
}


Somewhere in the middle of threadaux.d:

version(MinGW)
{
	void** teb;
	asm
	{
		".intel_syntax noprefix\n"
		"mov EAX,FS:[0x18]\n"
		"ret\n"
		".att_syntax noprefix\n"
		:"=a"(teb);
	}
	return teb;
}
else version(Win32)
{
	asm
	{
		naked;
		mov EAX,FS:[0x18];
		ret;
	}
}
else version(Win64)
{ snip }


More information about the D.gnu mailing list