x64 可移植可执行部分顺序
x64 Portable Executable section order
可移植可执行文件 (.exe) 文件格式中的 3 个基本部分:.data(资源)、.rdata(导入)和 .text(指令)是否可以按任意顺序排列,只要 'Address of Entry Point' 字段指向.text 部分?将说明 (.text) 放在首位似乎是一个很大的麻烦,因为您必须计算导入和资源部分才能实际编写说明部分...
这就是我要说的:https://i.imgur.com/LIImg.jpg
运行 时间表现如何?
PE文件的格式在pecoff.doc document中有详细说明(直接link到Word2003文件)。您所问的内容在第 4 章中有所介绍,它讨论了第 Table 节。最相关的细节:
The number of entries in the Section Table is given by the NumberOfSections field in the file header. Entries in the Section Table are numbered starting from one. The code and data memory section entries are in the order chosen by the linker.
所以不,这不是一成不变的,部分可以按任何顺序出现。
It seems like having the instructions (.text) be first is a big pain
正如 pecoff 语言所暗示的,这是一个 linker 实现细节。对于 Microsoft 的 linker 以及可能大多数其他 linker 来说,这实际上并不是什么大问题。它的首要工作是生成可执行代码,并且往往有很多。并没有使用所有代码,只是解决依赖关系所需的代码。这是一个 非常 常见的场景,静态 C 运行时库将是一个典型的例子。您的程序不会调用所有可能的运行时函数,linker 仅 link 需要什么。
搬迁和进口等细节是次要细节,只是数量不多。因此,首先 生成代码并跟踪所需的重定位和导入以匹配内存中的代码,然后将它们写入 PE 文件的效率要高得多。
您假设 "better" 反过来是不准确的。无论如何给 linker。
正如 已经回答的那样,链接器可以自由地以任何顺序排列部分,以最合适的方式排列。唯一的例外是命名部分,如 .text$A
和 .text$B
,其中部分 必须 根据 $
后的后缀按字典顺序排序。
链接器写入这些部分的顺序对于生成最终二进制文件的难易程度也没有太大意义。通常,二进制文件不会在计算部分时按顺序写入;相反,节内容是在缓冲区中生成的,并且代码和数据之间的引用保持符号化(以 relocatable 格式),直到节被写入最终的 executable.
问题中与性能相关的部分更多地与 Windows 中的 image loader 的工作方式有关,而不是 linker。因为加载程序不需要任何特定顺序的部分,所以在将部分解压缩到图像文件的内存视图时没有额外的开销(例如与排序相关的开销)。 import 和 export table 之间的搬迁和匹配是无论如何都要完成的,工作量由其他因素决定。因此,链接器决定的顺序本身不会影响加载时间。
对于正常的 Windows API 或本机二进制文件(不是 CLR),部分名称也不重要——只有每个部分的 characteristics 决定,例如映像中内存映射页的访问权限(是否只读、writable、executable等)。例如,导入 table 可能放在名为 .idata
而不是 .rdata
的部分中,或者该部分的名称可能完全不同。
可移植可执行文件 (.exe) 文件格式中的 3 个基本部分:.data(资源)、.rdata(导入)和 .text(指令)是否可以按任意顺序排列,只要 'Address of Entry Point' 字段指向.text 部分?将说明 (.text) 放在首位似乎是一个很大的麻烦,因为您必须计算导入和资源部分才能实际编写说明部分...
这就是我要说的:https://i.imgur.com/LIImg.jpg
运行 时间表现如何?
PE文件的格式在pecoff.doc document中有详细说明(直接link到Word2003文件)。您所问的内容在第 4 章中有所介绍,它讨论了第 Table 节。最相关的细节:
The number of entries in the Section Table is given by the NumberOfSections field in the file header. Entries in the Section Table are numbered starting from one. The code and data memory section entries are in the order chosen by the linker.
所以不,这不是一成不变的,部分可以按任何顺序出现。
It seems like having the instructions (.text) be first is a big pain
正如 pecoff 语言所暗示的,这是一个 linker 实现细节。对于 Microsoft 的 linker 以及可能大多数其他 linker 来说,这实际上并不是什么大问题。它的首要工作是生成可执行代码,并且往往有很多。并没有使用所有代码,只是解决依赖关系所需的代码。这是一个 非常 常见的场景,静态 C 运行时库将是一个典型的例子。您的程序不会调用所有可能的运行时函数,linker 仅 link 需要什么。
搬迁和进口等细节是次要细节,只是数量不多。因此,首先 生成代码并跟踪所需的重定位和导入以匹配内存中的代码,然后将它们写入 PE 文件的效率要高得多。
您假设 "better" 反过来是不准确的。无论如何给 linker。
正如 .text$A
和 .text$B
,其中部分 必须 根据 $
后的后缀按字典顺序排序。
链接器写入这些部分的顺序对于生成最终二进制文件的难易程度也没有太大意义。通常,二进制文件不会在计算部分时按顺序写入;相反,节内容是在缓冲区中生成的,并且代码和数据之间的引用保持符号化(以 relocatable 格式),直到节被写入最终的 executable.
问题中与性能相关的部分更多地与 Windows 中的 image loader 的工作方式有关,而不是 linker。因为加载程序不需要任何特定顺序的部分,所以在将部分解压缩到图像文件的内存视图时没有额外的开销(例如与排序相关的开销)。 import 和 export table 之间的搬迁和匹配是无论如何都要完成的,工作量由其他因素决定。因此,链接器决定的顺序本身不会影响加载时间。
对于正常的 Windows API 或本机二进制文件(不是 CLR),部分名称也不重要——只有每个部分的 characteristics 决定,例如映像中内存映射页的访问权限(是否只读、writable、executable等)。例如,导入 table 可能放在名为 .idata
而不是 .rdata
的部分中,或者该部分的名称可能完全不同。