
"Aaron W. LaFramboise" <aaronrabiddog51@aaronwl.com> wrote in message news:40C6168B.20400@aaronwl.com... [snip]
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),
Ok. a linker that minimally supports
TLS, and possibly some "glue code" to support the linker.
... meaning?
Presently, 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) #pragma code_seg(".CRT$XLA") BOOL WINAPI TlsCallback(HINSTANCE, DWORD, LPVOID) { <whatever> return TRUE; } #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 than DllMain).
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. // Johan