{"id":5623,"date":"2013-01-08T07:00:00","date_gmt":"2013-01-08T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/01\/08\/understanding-the-classical-model-for-linking-taking-symbols-along-for-the-ride\/"},"modified":"2013-01-08T07:00:00","modified_gmt":"2013-01-08T07:00:00","slug":"understanding-the-classical-model-for-linking-taking-symbols-along-for-the-ride","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130108-00\/?p=5623","title":{"rendered":"Understanding the classical model for linking: Taking symbols along for the ride"},"content":{"rendered":"<p><P>\nLast time, we learned the basics of\n<A HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2013\/01\/07\/10382714.aspx\">\nthe classical model for linking<\/A>.\nToday, we&#8217;ll look at the historical background for that model,\nand how the model is exploited by libraries.\n<\/P>\n<P>\nIn the classical model,\ncompilers and assemblers consume source code and spit out\nan OBJ file.\nThey do as much as they can, but eventually they get stuck\nbecause they don&#8217;t have the entire module at their disposal.\nTo record the work remaining to be done, the OBJ file contains\nvarious sections:\na data section, a code section (historically\nand confusingly called <I>text<\/I>),\nan uninitialized data section, and so on.\nThe linker resolves symbols, and then for each OBJ file\nthat got pulled into the module,\nit combines all the code sections into one giant code section,\nall the data sections into one giant data section, and so on.\n<\/P>\n<P>\nOne thing you may have noticed is that the unit of consumption\nis the OBJ file.\nIf an OBJ file is added to the module,\nthe whole thing gets added,\n<A HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/04\/27\/10002865.aspx\">\neven if you needed only a tiny part<\/A>\nof the OBJ file.\nHistorically,\nthe reason for this rule is that the compilers and assemblers\ndid not include information in the OBJ file to indicate\nhow to separate all the little pieces.\nIt&#8217;s like if somebody said,\n&#8220;Can you get me a portable mp3 player?&#8221;\nand the only thing available in the library\nwas a smartphone.\nSure, it plays mp3 files, but there&#8217;s a lot of other\nelectronic junk in there that you <I>didn&#8217;t<\/I> ask for,\nbut it came along for the ride.\nAnd you don&#8217;t know how to disassemble the smartphone\nand extract just the mp3-player part.\n<\/P>\n<P>\nThis behavior is actually exploited as a <I>feature<\/I>,\nbecause it allows for tricks like this:\n<\/P>\n<PRE>\n\/* magicnumber.h *\/\nextern int magicNumber;<\/p>\n<p>\/* magicnumber.c *\/\nint magicNumber;<\/p>\n<p>class InitMagicNumber\n{\n InitMagicNumber()\n {\n    magicNumber = &#8230;;\n }\n}\ng_InitMagicNumber;\n<\/PRE>\n<P>\nI&#8217;m not going to go into the magic of\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/7977wcck.aspx\">\nhow the compiler knows to construct the\n<CODE>g_Init&shy;Magic&shy;Number<\/CODE>\nobject at module entry<\/A>;\nI&#8217;ll let you read up on that.\n<\/P>\n<P>\nThe point is that if anybody in the module refers\nto the <CODE>magic&shy;Number<\/CODE> variable,\nthen that causes <CODE>magic&shy;number.obj<\/CODE>\nto be pulled into the module, which brings in not\njust the <CODE>magic&shy;Number<\/CODE> variable,\nbut also the\n<CODE>g_Init&shy;Magic&shy;Number<\/CODE> object,\nwhich initializes the magic number when\nthe process starts.\n<\/P>\n<P>\nOne place the C runtime library took advantage of this\nwas in deciding whether or not to include floating point\nsupport.\n<\/P>\n<P>\nAs you may recall, the 8086 processor did not have\nnative floating support.\nYou had to buy the 8087 coprocessor for that.\nIt was therefore customary for programs of that era\nto include a floating point library if they\ndid any floating point arithmetic.\nThe library would redirect floating point\noperations from the coprocessor to the emulator.\n<\/P>\n<P>\nThe floating point emulation library was pretty\nhefty, and it would have been a waste to include\nit for programs that didn&#8217;t use floating point\n(which was most of them),\nso the compiler used a trick to allow it to pull\nin the floating point library only if the\nprogram used floating point:\nIf you used floating point,\nthen the compiler added a <I>needed<\/I> symbol\nto your OBJ file:\n<CODE>__fltused<\/CODE>.\n<\/P>\n<P>\nThat magical\n<CODE>__fltused<\/CODE> symbol was marked as\n<I>provided<\/I>\nby&#8230; the floating point emulation library!\n<\/P>\n<P>\nThe linker found the symbol in an OBJ in\nthe floating point emulation library,\nand that served as the loose thread that\ncaused the rest of the floating point\nemulation library to be pulled into your module.\n<\/P>\n<P>\nNext time,\nwe&#8217;ll look at the interaction between OBJ files and LIB files.\n<\/P>\n<P>\n<B>Bonus reading<\/B>:\nLarry Osterman gives\n<A HREF=\"http:\/\/blogs.msdn.com\/b\/larryosterman\/archive\/2004\/09\/27\/234840.aspx\">\nanother example<\/A>\nof this trick.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, we learned the basics of the classical model for linking. Today, we&#8217;ll look at the historical background for that model, and how the model is exploited by libraries. In the classical model, compilers and assemblers consume source code and spit out an OBJ file. They do as much as they can, but eventually [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25,131],"class_list":["post-5623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code","tag-linker"],"acf":[],"blog_post_summary":"<p>Last time, we learned the basics of the classical model for linking. Today, we&#8217;ll look at the historical background for that model, and how the model is exploited by libraries. In the classical model, compilers and assemblers consume source code and spit out an OBJ file. They do as much as they can, but eventually [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/5623","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=5623"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/5623\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=5623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=5623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=5623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}