是否在编译时和运行时都调用了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?的主要内容,如果未能解决你的问题,请参考以下文章