CRTInitialization
ThistopicdescribeshowtheCRTinitializesglobalstatesinnativecode.
Bydefault,thelinkerincludestheCRTlibrary,whichprovidesitsownstartupcode.ThisstartupcodeinitializestheCRTlibrary,callsglobalinitializers,andthencallstheuser-providedmainfunctionforconsoleapplications.
InitializingaGlobalObject
Considerthefollowingcode:
int func(void)
{
return 3;
}
int gi = func();
int main()
{
return gi;
}
AccordingtotheC/C++standard,func()mustbecalledbeforemain()isexecuted.Butwhocallsit?
Onewaytodeterminethisistosetabreakpointinfunc(),debugtheapplication,
andexaminethestack.ThisispossiblebecausetheCRTsourcecodeisincludedwithVisualStudio.
Whenyoubrowsethefunctionsonthestack,youwillfindthattheCRTisloopingthroughalistoffunctionpointersandcallingeachoneasitencountersthem.Thesefunctionsareeithersimilartofunc()orconstructorsforclassinstances.
TheCRTobtainsthelistoffunctionpointersfromtheVisualC++compiler.Whenthecompilerseesaglobalinitializer,itgeneratesadynamicinitializerinthe.CRT$XCUsection(whereCRTisthesectionnameandXCUisthegroupname).Toobtainalistofthosedynamicinitializersrunthecommanddumpbin/allmain.obj,andthensearchthe.CRT$XCUsection(whenmain.cppiscompiledasaC++file,notaCfile).Itwillbesimilartothefollowing:
SECTION HEADER #6
.CRT$XCU name
0 physical address
0 virtual address
4 size of raw data
1F2 file pointer to raw data (000001F2 to 000001F5)
1F6 file pointer to relocation table
0 file pointer to line numbers
1 number of relocations
0 number of line numbers
40300040 flags
Initialized Data
4 byte align
Read Only
RAW DATA #6
00000000: 00 00 00 00 ....
RELOCATIONS #6
Symbol Symbol
Offset Type Applied To Index Name
-------- ---------------- ----------------- -------- ------
00000000 DIR32 00000000 C ??__Egi@@YAXXZ (void __cdecl `dynamic initializer for 'gi''(void))
The CRT defines two pointers:
__xc_a in .CRT$XCA
__xc_z in .CRT$XCZ
Bothgroupsdonothaveanyothersymbolsdefinedexcept__xc_aand__xc_z.Now,whenthelinkerreadsvarious.CRTgroups,itcombinestheminonesectionandordersthemalphabetically.Thismeansthattheuserdefinedglobalinitializers(whichtheVisualC++compilerputsin.CRT$XCU)willalwayscomeafter.CRT$XCAandbefore.CRT$XCZ.
Thesectionwillresemblethefollowing:
.CRT$XCA
__xc_a
.CRT$XCU
Pointer to Global Initializer 1
Pointer to Global Initializer 2
.CRT$XCZ
__xc_z
So,theCRTlibraryusesboth__xc_aand__xc_ztodeterminethestartandendoftheglobalinitializerslistbecauseofthewayinwhichtheyarelaidoutinmemoryaftertheimageisloaded.