动态链接器是如何执行的 /proc/self/exe

How does the dynamic linker executes /proc/self/exe

在 Linux 上执行动态链接的可执行文件时,将调用动态链接器作为其解释器(在此 answer 中进行了描述)。如果我没理解错,运行:

$ ./dynamic_elf

将导致 Linux 执行:

/lib64/ld-linux.so.2 ./dynamic_elf

我很难理解这对 /proc/self/exe 有何影响。根据上面的逻辑,运行:

$ /proc/self/exe

将导致 Linux 执行:

/lib64/ld-linux.so.2 /proc/self/exe

现在,当动态链接器尝试在 /proc/self/exe 加载 elf 时,它不会指向动态链接器本身,因为 ld-linux.so.2 现在是 运行 可执行文件吗?

我知道 JustWorks 上面的命令,所以我错过了什么?

正如您所指出的,内核没有将执行的二进制文件作为路径传递给解释器:

$ /lib64/ld-linux-x86-64.so.2 /proc/self/exe
loader cannot load itself

虽然 glibc 动态链接器支持这种调用方法(将程序作为参数提供给 运行),但在解释型 ELF 二进制文件的正常执行过程中并不使用这种方法。事实上,内核将未经修改的execve参数提供给动态链接器。

动态链接器根本不 "load" 或 "execute" 解释的 ELF 二进制文件。内核将解释器和解释后的二进制文件加载到内存中,并在解释器的入口点开始执行。解释二进制文件的入口点通过辅助向量中的 AT_ENTRY 字段传递给解释器。

动态链接器然后执行必要的 运行 时间链接并跳转到 "real" 入口点。

如果您在执行正常的解释型 ELF 可执行文件时在 _start 上设置断点,则可以在 gdb 中观察到这一切。使用 "show args" 你会看到 "real" argv 没有任何额外的值,并且进程的内存映射已经加载了解释的二进制文件(在解释器有 运行 一条指令之前) .

#! 脚本按照您期望的方式工作(实际上是在操纵 argv 值)。