{"id":6073,"date":"2006-10-20T13:22:00","date_gmt":"2006-10-20T13:22:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2006\/10\/20\/crt-initialization\/"},"modified":"2019-02-18T18:54:40","modified_gmt":"2019-02-18T18:54:40","slug":"crt-initialization","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/crt-initialization\/","title":{"rendered":"CRT Initialization"},"content":{"rendered":"<p>Hi, I&rsquo;m George Mileka and I work on the Visual C++ libraries team. My team owns the CRT, ATL, MFC and STL&hellip;<\/p>\n<p>One subject I have always been interested in is the startup code and initialization. The subject got even more challenging as we started supporting mixing native and managed code in our binaries.<\/p>\n<p>Today I will talk about how the CRT initializes global states in the native world&hellip; <\/p>\n<p>By default, the linker includes the CRT library which provides its own startup code. The CRT startup code initializes the CRT library, calls global initializers, and finally calls user-provided &ldquo;main()&rdquo; function (for console applications).<\/p>\n<p>Now, consider the following code:<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int func(void)<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 3;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int gi = func();<br \/>&nbsp;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int main()<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return gi;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p>According to the C\/C++ standard, func() must be called before main() is executed. But who calls it?<\/p>\n<p>An easy way to know, is to set a breakpoint in func(), start debugging the application and look at the stack! Luckily, the CRT code ships with VS!<\/p>\n<p>Browsing the functions on the stack, you will find that the CRT is simply looping through a list of function pointers, calling each one as it goes through them. Those functions are either ones like func() or constructors for class instances&hellip;<\/p>\n<p>So, where does the CRT get that list from?<\/p>\n<p>There is a contract between the CRT and VC++ Compiler:<\/p>\n<ul>\n<li>When the VC++ compiler sees a global initializer, it generates a dynamic initializer in the .CRT$XCU section (note that the CRT is the section name and XCU is the group name). You can look at those dynamic initializers by running &ldquo;dumpbin \/all main.obj&rdquo;, and then looking at the .CRT$XCU section (when main.cpp is compiled as a cpp file, not a c file). It will have something like this:<\/li>\n<\/ul>\n<p>SECTION HEADER #C<\/p>\n<p>.CRT$XCU name<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>RELOCATIONS #C<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol&nbsp;&nbsp;&nbsp; Symbol<\/p>\n<p>&nbsp;Offset&nbsp;&nbsp;&nbsp; Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Applied To&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Index&nbsp;&nbsp;&nbsp;&nbsp; Name<\/p>\n<p>&nbsp;&#8212;&#8212;&#8211;&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;-&nbsp; &#8212;&#8212;&#8212;&#8212;&#8212;&#8211;&nbsp; &#8212;&#8212;&#8211;&nbsp; &#8212;&#8212;<\/p>\n<p>&nbsp;00000000&nbsp; DIR32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00000000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 26&nbsp; <a href=\"mailto:??__Egi@@YAXXZ\">??__Egi@@YAXXZ<\/a> (void __cdecl `dynamic initializer for &#8216;gi&#8221;(void))<\/p>\n<p>&nbsp;<\/p>\n<p>&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRT defines two pointers; <\/p>\n<p>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __xc_a in .CRT$XCA<\/p>\n<p>o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __xc_z in .CRT$XCZ<\/p>\n<p>Both groups do not have any other symbols defined except __xc_a and __xc_z.<\/p>\n<p>Now &ndash; when the linker reads various .CRT groups, it combines them in one section and orders them alphabetically. This means that the user-defined global initializers (which the VC++ compiler puts in .CRT$XCU) will always come after .CRT$XCA and before .CRT$XCZ. So, it should look something like:<\/p>\n<p>.CRT$XCA<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __xc_a<\/p>\n<p>.CRT$XCU<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pointer to Global Initializer 1<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pointer to Global Initializer 2<\/p>\n<p>.CRT$XCZ<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __xc_z<\/p>\n<p>So, the CRT library can use both __xc_a and __xc_z to determine the start and end of the global initializers list (array) because of how they are laid out in memory once the image is loaded.<\/p>\n<p>Please, send any questions, comments or feedback our way! We&rsquo;ll be happy to address them!<\/p>\n<p>George Mileka<br \/>Visual C++ Libraries Team<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi, I&rsquo;m George Mileka and I work on the Visual C++ libraries team. My team owns the CRT, ATL, MFC and STL&hellip; One subject I have always been interested in is the startup code and initialization. The subject got even more challenging as we started supporting mixing native and managed code in our binaries. Today [&hellip;]<\/p>\n","protected":false},"author":289,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-6073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>Hi, I&rsquo;m George Mileka and I work on the Visual C++ libraries team. My team owns the CRT, ATL, MFC and STL&hellip; One subject I have always been interested in is the startup code and initialization. The subject got even more challenging as we started supporting mixing native and managed code in our binaries. Today [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/6073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/289"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=6073"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/6073\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=6073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=6073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=6073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}