Boost logo

Boost :

From: Aaron W. LaFramboise (aaronrabiddog51_at_[hidden])
Date: 2004-06-09 03:43:12


Johan Nilsson wrote:

>"Aaron W. LaFramboise" <aaronrabiddog51_at_[hidden]> wrote in message
>news:40C6168B.20400_at_aaronwl.com...
>
>> <>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.
>
>> <>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 ...
>>
I have not exhaustively tested it due to lack of places to test. I am
fairly confident it works reliably on Win9x and Win2k/XP. I would
suspect it works on similar platforms. I don't have any idea about
older NTs, Longhorn, CE, Win32s, or non-IA32 platforms, other than that
the spec seems to indicate that it should work.

You probably didn't hear about it for the same reason I didn't until I
started studying the PE specification: there is no documented support
for it outside of the specification. It was only relatively recently
that I actually tried to use it, and was somewhat suprised when it
actually worked.

>>TLS, and possibly some "glue code" to support the linker.
>>
>>
>
>... meaning?
>
>
Well, I'm thinking more from an implementors point of view. The linker
requires a file, that should be provided by someone in the compiler
system, to define a few symbols the linker needs to set up the TLS
directory. More below.

>> Presently,
>>MSVC has the necessary support, and GNU targets MinGW and Cygwin have
>>all of the critical support as well, but lack the "glue."
>>
>>
I appologize; I misspoke on the fact that the MSVC support is complete.
I beleive this has something to do with missing support in tlssup.obj,
but I'm limited in my ability to investigate due to intellectual
property issues. Not too sure how to handle this.

>>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?
>
>
>
In C,
#include <stdio.h>
#include <windows.h>
void NTAPI my_callback (PVOID DllHandle, DWORD Reason, PVOID Reserved) {
  char buf[50];
  sprintf(buf, "0x%lx 0x%lx 0x%lx", (unsigned long)DllHandle,
    (unsigned long)Reason, (unsigned long)Reserved);
  MessageBox(0, buf, "callback", 0);
}
#pragma data_seg(push, old_seg)
#pragma data_seg(".CRT$XLB")
DWORD my_callback_ptr = (DWORD)my_callback;
#pragma data_seg(pop, old_seg)
int main() {
  printf("hi\n");
  return 0;
}

Note, this won't work because, as mentioned, for some reason it isn't
being added to the TLS directory

The parameters and all other docs on TLS callbacks are in "Microsoft
Portable Executable and Common Object File Format Specification Revision
6.0 - February 1999" 6.7.2, apparently freely availible by websearch.

Contrary to what I might have misleadingly stated before, no compiler
seems to directly support using this out of box. I don't know what is
wrong with Microsoft's tlssup.obj, if that is the problem. I do know
that the callbacks work in actual executables, and I have gotten it to
work on GNU binutils with some patches, and MSVC LINK with a replacement
for tlssup.obj.

It is my intention to get this feature working 100% on GNU GCC and
binutils, which I admit are my primary interest, but I am unsure about
MSVC. I am very hesitant to investigate MSVC any more than necessary as
I do not want to get myself into ridiculous IP problems.

I also neglected to mention that this feature may be unusable, in
general, because the TLS callbacks are called before the C library's
are. This means that stdio and the heap may not be fully availible, at
least for MSVC. The standard C library (and perhaps other DLLs?) need
to expect that they may not be notified first of ctors/dtors. MSVCRT
may do this, but I am not sure. I don't know what garentees there are
about MSVCRT.DLL being notified before any other loaded DLL, anyway.

So, well, I have no idea how helpful this is to anyone, and I'm
painfully aware of how hypocritical it is to not be able to provide a
simple testcase. I just wanted to let people know that Windows seems to
have this capability, and that the GNU environment on Windows will
probably support this sometime soon.

Aaron W. LaFramboise


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk