【问题标题】:Is ld called at both compile time and runtime?ld 在编译时和运行时都调用吗?
【发布时间】:2018-08-31 15:36:18
【问题描述】:

我正在尝试了解链接和加载的工作原理。我的理解是 Unix 程序“ld”包含链接和加载功能。当 gcc 被调用时,在预处理、编译和组装之后,链接器被调用,它将所有目标文件和 .a 文件链接到一个可执行文件中,以及关于如何“连接”共享库的最少指令(这里的正确术语是什么?) 在运行时。这个链接器是 ld。

在运行时,我的理解是可执行文件被加载到内存中,尽管我不确定如何加载。我的具体问题如下:

1) 共享对象文件是否在编译时被“链接”,或者对于正在发生的事情是否有另一种说法? 2) 在运行时,ld 是否被第二次调用?我如何才能看到我的可执行文件(在 Linux 和 MacOS 上)的证明? 3) 共享对象文件是否在运行时被“链接”,或者在运行时从 LD_LIBRARY_PATH 中的位置读取共享对象时,进程是否有另一个词?

谢谢!

【问题讨论】:

    标签: compilation linker


    【解决方案1】:

    ld 在编译时和运行时都被调用吗?

    否:ld 不是在编译或运行时调用的。

    当 gcc 被调用时,在预处理、编译和组装之后,链接器被调用,它将所有目标文件和 .a 文件链接到一个可执行文件中

    大多数中等复杂的程序使用单独的编译和链接步骤。

    在编译时,会生成一组可重定位的目标文件(在该步骤调用预处理、编译和组装)。可以选择将.o 文件归档到归档库 (libsomething.a) 中。

    然后执行链接步骤(通常称为“静态链接”,以将此步骤与运行时发生的“动态加载”区分开来),生成可执行文件或共享库.仅在 this 步骤调用/usr/bin/ld。在 Linux 上,ld 是 binutils 包的一部分。

    以及如何“连接”共享库的最少说明

    链接器记录运行时需要哪些共享库,可能还需要哪些版本的库或符号。

    它还记录应该使用哪个运行时加载器来加载所需的共享库。

    在运行时,我的理解是可执行文件被加载到内存中,虽然我不确定如何。

    内核将可执行文件加载到内存中,并检查是否在静态链接时请求了运行时加载程序。如果是,则动态加载器加载到内存中,并将执行控制权传递给它(而不是主可执行文件)。

    然后动态加载器的工作是检查可执行文件中需要其他库的指令,检查是否可以找到正确的版本,将它们加载到内存中,并安排一些事情以使符号解析在主程序之间起作用可执行文件和共享库。 是运行时加载步骤,通常也称为动态链接。

    动态加载器可以是操作系统的一部分,但在 Linux 上它是 libc 的一部分(GLIBC、uClibc 和 musl 都有自己的加载器)。

    【讨论】:

      【解决方案2】:

      没有。 ld 在创建库或 exe 时进行链接,ld*.so 是加载部分。 ld*.so 也是操作系统的一部分,而不是 gcc 套件 afaik。 ld 通常是基于 gcc 的系统上 (GNU) binutils 的一部分(例如,通常是基于 LLVM 的系统中的 LLVM lld)

      ld*.so 在 Linux 上是 ld-linux-{arch}.so.2,在例如 /libexec/ld-elf.so 上是FreeBSD。

      【讨论】:

      • ld-linux 不是 Linix 操作系统的一部分。您可以在同一系统上同时安装多个不同的。
      • 它似乎是 glibc 的一部分。然而,这种知识在逻辑上没有意义。然而,我的观点更多的是它不是可移植到其他操作系统(如 binutils 和 gcc)的部分的一部分。
      猜你喜欢
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 2010-12-29
      • 2014-04-11
      相关资源
      最近更新 更多