C 各种程序如何引用共享库?

C 各种程序如何引用共享库?,c,C,我知道共享库被加载到内存中,并被各种程序使用。 程序如何知道库在内存中的位置?使用共享库时,链接过程有两个部分。在编译时,Linux中的链接器程序(ld)链接共享库,以了解它定义了哪些符号。但是,共享库中的任何代码或数据初始值设定项实际上都没有包含在ultimatea.out文件中。相反,ld只记录链接所针对的动态库,并将信息放入a.out文件的辅助部分 第二个阶段在调用main之前的执行时进行。内核将一个小的帮助程序ld.so,加载到地址空间,然后执行。因此,程序的起始地址不是main,甚至不

我知道共享库被加载到内存中,并被各种程序使用。

程序如何知道库在内存中的位置?

使用共享库时,链接过程有两个部分。在编译时,Linux中的链接器程序(ld)链接共享库,以了解它定义了哪些符号。但是,共享库中的任何代码或数据初始值设定项实际上都没有包含在ultimate
a.out
文件中。相反,
ld
只记录链接所针对的动态库,并将信息放入
a.out
文件的辅助部分

第二个阶段在调用
main
之前的执行时进行。内核将一个小的帮助程序
ld.so
,加载到地址空间,然后执行。因此,程序的起始地址不是
main
,甚至不是
\u start
(如果您听说过的话)。相反,它实际上是动态库加载器的起始地址

在Linux中,内核将
ld.so
loader代码映射到进程地址空间中一个方便的位置,并设置堆栈,以便显示所需的共享库列表(以及其他必要的信息)。动态加载程序通过查看一系列目录来查找每个所需的库,这些目录通常位于环境变量
LD\u LIBRARY\u PATH
中。还有一个预定义的列表,它被硬编码到
ld。因此
(在链接期间,额外的搜索位置可以硬编码到
a.out
)。对于每个库,动态加载程序读取其标题,然后使用
mmap
为库创建内存区域

现在来看有趣的部分

由于在运行时用于满足需求的实际库在链接时是未知的,因此我们需要找到一种方法来访问共享库中定义的函数和共享库导出的全局变量(由于导出全局变量不是线程安全的,所以不推荐使用这种做法,但我们仍然尝试处理它)

全局变量在链接时被分配一个静态地址,然后由绝对内存地址访问

对于库导出的函数,库的用户将发出一系列
调用
汇编指令,这些指令引用绝对内存地址。但是,在链接时,引用函数的确切绝对内存地址未知。我们如何处理

链接器创建了一个称为过程链接表,它是一系列
jmp
(汇编跳转)指令。跳转的目标在运行时填写

现在,在处理代码的动态部分时(即使用
-fpic
编译的
.o
文件),没有绝对内存引用。为了访问代码静态部分也可见的全局变量,使用另一个名为全局偏移表的表。该表是指针数组。在链接时,由于全局变量的绝对内存地址已知,因此nker填充此表。然后,在运行时,动态代码可以通过以下方式访问全局变量:首先查找全局偏移量表,然后从表中的适当插槽加载正确变量的地址,最后取消对指针的引用。

请使用。祝您好运。