我很想知道Loader如何将DLL映射到处理地址空间。装载机如何做到这一点。例子非常受欢迎。
提前致谢。
答案 0 :(得分:9)
好的,我在这里假设Windows方面。加载PE文件时会发生的情况是加载程序(包含在NTDLL中)将执行以下操作:
DLLMain()
创建一个线程,其起始地址位于PE文件的入口点(这也是过于简化的,因为实际的起始地址位于kernel32.dll for Win32进程内) 现在编译代码时,它依赖于链接器如何引用外部函数。一些链接器创建存根,以便 - 理论上 - 尝试检查函数地址与NULL将始终说它不是NULL。如果链接器受到影响,您必须注意这一点。其他人直接引用IAT条目,在这种情况下,未引用的函数(认为延迟加载的DLL)地址可以为NULL,然后SEH处理程序将调用延迟加载帮助程序并(尝试)解析函数地址,然后再继续执行指出它失败了。
上述过程中涉及大量繁文缛节,我过于简单了。
您想知道的要点是,流程映射是以MMF 形式发生的,尽管您可以人为地模仿堆空间的行为。但是,如果你还记得关于CoW的观点,那就是DLL概念的关键。实际上,DLL的(大部分)页面的相同副本将在加载特定DLL的进程之间共享。未共享的页面是我们写入的页面,例如在解析重定位和类似事物时。在这种情况下,每个进程都有一个 - 现在已修改 - 原始页面的副本。
关于DLL的EXE打包程序的警告。它们完全打败了我所描述的这种CoW机制,因为它们在DLL加载到的进程堆上为DLL的解包内容分配空间。因此,虽然实际的文件内容仍然映射为MMF并且共享,但是解压缩的内容对于加载DLL而不是共享DLL的每个进程占用相同的内存量。
答案 1 :(得分:7)
您在寻找什么级别的细节?在基本层面上,所有动态链接器的工作方式几乎相同:
答案 2 :(得分:3)
如果您真的感兴趣,请阅读本书Linkers and Loaders。
答案 3 :(得分:2)
假设这是在Windows中(DLL提示),您可能想要阅读Microsoft的Run-Time Dynamic Linking文档页面。它没有详细说明如何将 DLL映射到地址空间;我想你不应该知道这一点。