/TSAWARE 链接器标志对 PE 可执行文件有什么作用?

And*_*ers 4 windows linker visual-c++-6 portable-executable visual-c++

将 /TSAWARE 链接器标志添加到我的一个项目 (Visual Studio 6) 后,我惊讶地发现 PE 文件 (.idata) 中有一个新部分。如果我不设置标志,导入将合并到 .rdata 中。

为了说明“问题”,我们从一个简单的控制台程序开始:

#include <stdio.h>
int main() 
{
    printf("hello world\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并编译: 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
Run Code Online (Sandbox Code Playgroud)

因此,出于某种原因,链接器决定无法合并导入。

但是如果我们editbin /TSAWARE a.exe只运行PE 可选头中的 DLL 特性字段会发生变化。

任何人都可以向我解释这一点吗?这是链接器中的错误还是由 editbin 更改的可执行文件最终无法在某些系统上运行?

Mic*_*urr 5

只是猜测:在终端服务器系统上,您希望图像尽可能多地写入几页。如果与映像对应的内存页未被修改,则可以将物理 RAM 的单个页映射到使用该映像的 eash 会话中。如果修改了图像中的页面,则系统必须为所有会话中的每个页面实例执行写时复制操作,并使用不同的物理内存块来表示每个会话中的页面。

如果导入的 DLL 必须重新定位,通常需要修复图像的导入,因此保存导入的页面经常被修改,因此无法参与会话之间的共享。如果链接器将导入与通常未修改的其他数据合并,则可能会不必要地增加写时复制页面的数量。

这可能是一种优化,有助于减少跨会话复制的页面数量。

就像我说的 - 这纯粹是一个猜测。