{"id":109084,"date":"2023-11-30T07:00:00","date_gmt":"2023-11-30T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=109084"},"modified":"2023-11-30T09:43:33","modified_gmt":"2023-11-30T17:43:33","slug":"20231130-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20231130-00\/?p=109084","title":{"rendered":"Why does the Windows Portable Executable (PE) format have separate tables for import names and import addresses?, part 2"},"content":{"rendered":"<p>In the Windows Portable Executable (PE) format, the image import descriptor table describes the functions imported from a specific target DLL.<\/p>\n<pre>struct IMAGE_IMPORT_DESCRIPTOR {\r\n    DWORD   OriginalFirstThunk;\r\n    DWORD   TimeDateStamp;\r\n    DWORD   ForwarderChain;\r\n    DWORD   Name;\r\n    DWORD   FirstThunk;\r\n};\r\n<\/pre>\n<p>The <code>OriginalFirstThunk<\/code> points to an array of pointer-sized <code>IMAGE_THUNK_DATA<\/code> structures which describe the functions being imported. The <code>FirstThunk<\/code> points to an array of pointers, whose initial values are a copy of the values pointed to by <code>OriginalFirstThunk<\/code>.<\/p>\n<p>Last time, <!-- backref: Why does the Windows Portable Executable (PE) format have separate tables for import names and import addresses?, part 1 --> we looked at why the two identical tables can&#8217;t be merged: Because the second table can be modified by binding, and then the two copies both contain distinct information that is needed at run time.<\/p>\n<p>Okay, so you can&#8217;t merge the two tables, but why not combine them into a single mega-table? Why split it into two mini-tables?<\/p>\n<p>The tables are kept separate because one is read-only and the other is read-write. Splitting them up allows the read-only part to be combined with other read-only data, and the read-write part to be combined with other read-write data. This allows for a reduction in the number of read-write pages. This benefit could end up being small for a single DLL, but if the DLL is used by many processes, the multiplicative effect can be significant.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Keeping read-only data separate from read-write data.<\/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":[26],"class_list":["post-109084","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Keeping read-only data separate from read-write data.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109084","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=109084"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109084\/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=109084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=109084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=109084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}