将 /TSAWARE 链接器标志添加到我的一个项目 (Visual Studio 6) 后,我惊讶地发现 PE 文件 (.idata) 中出现了一个新部分。如果我不设置该标志,导入将合并到 .rdata 中。
为了说明“问题”,我们从一个简单的控制台程序开始:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
并编译:cl /Og /O1 /GF /WX /c main.c
然后链接到
link /MACHINE:IX86 /SUBSYSTEM:CONSOLE /RELEASE /OUT:a.exe main.obj
link /MACHINE:IX86 /SUBSYSTEM:CONSOLE /RELEASE /OUT:b.exe /TSAWARE main.obj
让我们比较一下 dumpbin 的输出:
Dump of file a.exe
File Type: EXECUTABLE IMAGE
Summary
4000 .data
1000 .rdata
5000 .text
Dump of file b.exe
File Type: EXECUTABLE IMAGE
Summary
4000 .data
1000 .idata
1000 .rdata
5000 .text
因此,由于某种原因,链接器决定不能合并导入。
但如果我们跑editbin /TSAWARE a.exe
仅 PE 可选标头中的 DLL 特征字段发生变化。
谁能向我解释一下吗?这是链接器中的错误还是由 editbin 更改的可执行文件最终无法在某些系统上运行?
只是一个猜测:在终端服务器系统上,您希望图像尽可能写入几页。如果与该图像相对应的内存页没有被修改,则物理RAM的单页可以被映射到正在使用该图像的eash会话中。如果修改了映像中的页面,则系统必须为所有会话中页面的每个实例执行写时复制操作,并使用不同的物理内存块来表示每个会话中的页面。
由于如果必须重新定位正在导入的 DLL,则通常需要修复图像的导入,因此保存导入的页面通常会被修改,因此无法参与会话之间的共享。如果链接器将导入与通常不修改的其他数据合并,则可能会不必要地增加写时复制页的数量。
这可能是一种优化,有助于减少跨会话复制页面的数量。
就像我说的——这纯粹是一个猜测。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)