是否在编译时和运行时都调用了ld?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否在编译时和运行时都调用了ld?相关的知识,希望对你有一定的参考价值。

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

在运行时,我的理解是可执行文件被加载到内存中,虽然我不知道如何。我的具体问题如下:

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

谢谢!

答案

是否在编译时和运行时都调用了ld?

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

在调用gcc时,在预处理,编译和汇编之后,调用链接器将所有目标文件和.a文件链接到可执行文件中

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

在编译时,会生成一组可重定位目标文件(在该步骤调用预处理,编译和汇编)。可选地,.o文件存档到存档库(libsomething.a)中。

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

以及关于如何“连接”共享库的最小指示

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

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

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

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

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

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

另一答案

编号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?的主要内容,如果未能解决你的问题,请参考以下文章

编译时和运行时OC中对象的动态编译机制

-g 标志更改程序的运行时和编译

OpenGL First Cube渲染不起作用

是否可以动态编译和执行 C# 代码片段?

Java编译时注解和运行时注解有啥区别

CODEBLOCKS10.05 编译运行时 DOS窗口的中文显示为乱码?怎么解决?