From: Johan Nilsson (johan.nilsson_at_[hidden])
Date: 2004-06-09 02:34:02
"Aaron W. LaFramboise" <aaronrabiddog51_at_[hidden]> wrote in message
> There is a little-known mechanism present in the Windows executable
> support, called TLS callbacks, that can call a list of arbitrary
> functions when a process starts and exits, and when threads attach or
> detach (very similar to DllMain). The calls are made in the context of
> the relevent thread. No linked DLL or overriden or special thread
> functions are necessary, as with ordinary approaches.
That's cool - never heard of it before.
> Its likely that few people know about this because there are apparently
> no compilers that use it--that I am familiar with. It is presently only
> documented in the PE specification. However, it appears to work without
> problems on all versions of IA32 Windows, and quite likely on anything
> else that uses PE, also.
You've actually tried it under Win9x, NT4, w2k and XP/2003? Longhorn? I'm
not skeptical, just interested. In any case, if it's part of the official PE
documentation it should be possible. I just can't imagine why I've never
heard of this before ...
> Support for it requires minimal compiler support (the ability to emit
> data in arbitrarily-named sections, or even better, support for
> constructors and destructors in __declspec(thread), which no compiler I
> am familiar with has, including MSVC),
a linker that minimally supports
> TLS, and possibly some "glue code" to support the linker.
> MSVC has the necessary support, and GNU targets MinGW and Cygwin have
> all of the critical support as well, but lack the "glue."
> The way to do it is to emit a pointer to the function to be called
> (which has the same signature as DllMain) in any of the 25 sections
> .CRT$XLA through .CRT$XLY. The linker merges all of these sections into
> a single null-termniated table of function pointers and creates a
> pointer to it from the executable image's TLS directory.
Do you mean something as simple as (for msvc):
#pragma code_seg(push, old_seg)
BOOL WINAPI TlsCallback(HINSTANCE, DWORD, LPVOID)
#pragma code_seg(pop, old_seg)
What are the descriptions for the parameters above?
> I am presently using this feature on the GCC target MinGW for this
> purpose. I have not distributed my code, though, so there is no
> widespread testing.
> I am also not sure what the limitations are with regards to what
> functions may safely be called from the context of one of these
> callbacks. I assume it is similar to DllMain(), which it makes it
> dangerous to use this as a general-purpose mechanism to execute
> arbitrary code.
I would guess it has some (more or less) serious restrictions (but it
shouldn't need to hold the loader lock, making it somewhat less restrictive
> In particular, constructors often load DLLs as a side
> effect, particularly if lazy loading is being used, and this may cause
> difficult to diagnose or reproduce problems if one such constructor is
> being used in a TLS construction or destruction context. More research
> is required in this area.
> In any case, I think this mechanism is definitely something that should
> be examined if static thread support is being considered.
Definitely agreed on that.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk