当我在 Linux 中运行某些可执行文件时,是否有很好的文档说明会发生什么。例如:我 start ./a.out
,所以可能运行了一些引导加载程序程序集(带有 c 运行时?),它在程序中找到 start 符号,进行动态重定位,最后调用main
.
我知道上述内容不正确,但正在寻找有关此过程如何发生的详细文档。你能解释一下,或者指向链接或书籍吗?
当我在 Linux 中运行某些可执行文件时,是否有很好的文档说明会发生什么。例如:我 start ./a.out
,所以可能运行了一些引导加载程序程序集(带有 c 运行时?),它在程序中找到 start 符号,进行动态重定位,最后调用main
.
我知道上述内容不正确,但正在寻找有关此过程如何发生的详细文档。你能解释一下,或者指向链接或书籍吗?
对于动态链接程序,内核检测PT_INTERP
ELF 文件中的标头并首先映射动态链接器(或类似的),并从动态链接器的主 ELF 标头的地址/lib/ld-linux.so.2
开始执行。e_entry
堆栈的初始状态包含动态链接器查找主程序二进制文件(已经在内存中)所需的信息。它负责读取并查找所有必须加载的附加库,加载它们,执行重定位,并跳转到e_entry
主程序的地址。
对于静态链接程序,内核e_entry
直接使用主程序的 ELF 头中的地址。
在任何一种情况下,主程序都以一个用汇编语言编写的例程开始,传统上称为_start
(但名称并不重要,只要它的地址在e_entry
ELF 标头的字段中)。它使用初始堆栈内容来确定argc
、argv
、environ
等,并调用正确的内部实现函数(通常用 C 编写)来运行全局构造函数(如果有)并在进入main
. 这通常以调用exit(main(argc, argv));
或等效结束。
《Linker and Loader》一书详细描述了加载过程。也许它可以为您解决问题提供一些帮助。