Windows 如何在没有位置无关代码的情况下处理加载到内存中的多个 DLL?

How does Windows handle multiple DLLs loaded in memory without position independent code?

Linux 和 MacOS 利用位置无关代码的强大功能。 Windows 上没有这样的东西,但程序可以 link 通常针对共享 DLL。除了 Microsoft 网站 (here and here) 上的几篇简洁文章外,我似乎找不到关于此主题的好文档。 Windows是不是只是把内存中的DLL代码拷贝过来,根据需要调整函数地址?如果两个程序 link 针对同一个库怎么办?会不会涉及虚拟内存机制?

Windows PE (.exe/.dll) 文件包含重定位数据,如果代码加载到预期基地址以外的地址,加载程序可以根据需要调整地址。

重定位table本质上只是二进制文件中需要调整的偏移量列表,例如如果将基地址为 0x100000 的 .dll 加载到 0x300000,则重定位中包含的每个地址 table 都会添加 (0x300000 - 0x100000) = 0x200000。

有关 PE 文件的重定位数据格式的更多详细信息,以及此类文件的结构通常可以在此处找到:https://docs.microsoft.com/en-us/previous-versions/ms809762(v=msdn.10)#pe-file-base-relocations