ELF 的代码段何时加载到内存中?

When is the code section of an ELF loaded into memory?

当 ELF 格式的可执行文件在 linux 环境中 运行 时,文件的实际内容在什么时候加载到物理内存中?

操作系统的哪一部分对此负责?

内核加载 ELF exe 映像,无论映像 header 说到哪里。 (我们记得 Unix 完全依赖于虚拟内存才能正常运行,请参阅 fork()。)内核具有加载共享库的例程;然而,除了加载程序本身外,很少使用这些。然后内核跳转到映像中指定的起始地址。如果有loader,则劫持此跳转跳转到loader。

大多数共享库由加载程序加载(/lib/ld-linux-so.2 for i386),这是一个共享库。加载器可以做一些事情,比如定位共享库在系统中的位置,而不是像内核必须做的那样依赖于嵌入在 exe 映像中的绝对路径。加载程序将库映射到内存并执行修复。加载程序保持加载在内存中,可用于按需加载其他库(请参阅 dlopen())。

LWN 上有一篇关于这个的详细文章:https://lwn.net/Articles/631631/

特别是,代码由 load_elf_binary() 加载:http://lxr.free-electrons.com/source/fs/binfmt_elf.c?v=3.18#L571

该函数是从 do_execve_common()(间接)调用的,当然是从 execve() 和朋友们调用的:http://lxr.free-electrons.com/source/fs/exec.c?v=3.18#L1513

您可能已经知道,execve() 和朋友通常在创建新进程后立即被调用(通过 fork())。所以 "create a process" 和 "load the ELF."

之间的差距很小

最后,由 MMU 的硬件异常调用的页面错误处理程序将代码从虚拟内存加载到物理内存。