【问题标题】:How does the dynamic linker executes /proc/self/exe动态链接器如何执行 /proc/self/exe
【发布时间】:2020-05-07 22:20:30
【问题描述】:

在 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 加载精灵时,它会不会指向动态链接器本身,因为ld-linux.so.2 现在是正在运行的可执行文件?

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

  • 动态链接器获得的是否超过了调用它的精灵的路径?

  • 这里的语义和shebang#!)解释器有区别吗?

【问题讨论】:

    标签: linux ld dynamic-linking procfs


    【解决方案1】:

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

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

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

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

    然后动态链接器执行必要的运行时链接并跳转到“真正的”入口点。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多