#pragma section(".CRTMP$XCA",long,read)
#pragma section(".CRTMP$XCZ",long,read)
#pragma section(".CRTMP$XIA",long,read)
#pragma section(".CRTMP$XIZ",long,read)
#pragma section(".CRTMA$XCA",long,read)
#pragma section(".CRTMA$XCZ",long,read)
#pragma section(".CRTMA$XIA",long,read)
#pragma section(".CRTMA$XIZ",long,read)
#pragma section(".CRTVT$XCA",long,read)
#pragma section(".CRTVT$XCZ",long,read)
These sections are used for initializers of globals when you are building a managed binary. The $XI are C initializes while the $XC are C++ initializers. The MP means managed per process, while the MA means managed per app domain. The VT stands for VTABLE, in other words your virtual method initializers. I found this all in crt\src\mstartup.cpp. Something interesting is the C initializers are never called.
#pragma section(".CRT$XCA",long,read)
#pragma section(".CRT$XCC",long,read)
#pragma section(".CRT$XCZ",long,read)
#pragma section(".CRT$XIA",long,read)
#pragma section(".CRT$XIC",long,read)
#pragma section(".CRT$XID",long,read)
#pragma section(".CRT$XIY",long,read)
#pragma section(".CRT$XIZ",long,read)
These sections are used for native initializers. Like before $XI are C while $XC are C++ initializers. The XCC section is the list of C++ initializers and the XIC are the C initializers. The XID and XIY seems to be a special sections of C initializers that are to be run after all the C initializers
#pragma section(".CRT$XCAA",long,read)
#pragma section(".CRT$XIAA",long,read)
These sections are for native PRE-initializers. That is, they are run before the above initializers.
#pragma section(".CRT$XPA",long,read)
#pragma section(".CRT$XPB",long,read)
#pragma section(".CRT$XPX",long,read)
#pragma section(".CRT$XPXA",long,read)
#pragma section(".CRT$XPZ",long,read)
#pragma section(".CRT$XTA",long,read)
#pragma section(".CRT$XTB",long,read)
#pragma section(".CRT$XTX",long,read)
#pragma section(".CRT$XTZ",long,read)
These are C terminators (read destructors), that get called on exit. $XP are pre-terminators, and $XT are normal terminators.
#pragma section(".CRT$XDA",long,read)
#pragma section(".CRT$XDC",long,read)
#pragma section(".CRT$XDL",long,read)
#pragma section(".CRT$XDU",long,read)
#pragma section(".CRT$XDZ",long,read)
These are used for Thread Local Storage dynamic initializers. You can find a detailed explanation in crt\src\tlsdyn.c.
#pragma section(".CRT$XLA",long,read)
#pragma section(".CRT$XLC",long,read)
#pragma section(".CRT$XLD",long,read)
#pragma section(".CRT$XLZ",long,read)
These seem to be for bootstrapping for Thread Local Storage. From a comment in src\crt\tlssup.c
/* Start section for TLS callback array examined by the OS loader code.
* If dynamic TLS initialization is used, then a pointer to __dyn_tls_init
* will be placed in .CRT$XLC by inclusion of tlsdyn.obj. This will cause
* the .CRT$XD? array of individual TLS variable initialization callbacks
* to be walked.
*/
If I understand this correctly, it means that if you have Thread Local Storage enabled, a pointer to __dyn_tls_init will be placed in .CRT$XLC, which should cause it to be called and your TLS to be initialized as needed. The XLD points to _dyn_tls_dtor, which calls the destructors for Thread Local Storage.
For an explanation on what these sections are used for read this blog
Thanks! It's really helps
ReplyDelete