动态加载库(DSO)中的符号导入

时间:2014-05-20 23:14:01

标签: c dynamic dll

让我们说我正在创建共享对象库libz.so,其中包含一个头文件,例如stdio.h。作为libc库一部分的stdio.h代码在系统中静态链接。动态链接器如何解析从DSO到静态链接的libc文件的符号引用?

例如: 让我们说我用以下代码将z.c文件编译成SO。

#include <stdio.h>

int foo(void){
  printf("hello world!\n");
}

动态链接器如何知道静态链接的libc中printf的位置并在运行时修补printf地址?

1 个答案:

答案 0 :(得分:0)

通常,假设静态库使用与共享库兼容的ABI(在所有平台上都不是这种情况),则将符号解析委托给动态链接器。

如果您的DSO已经静态链接到libc,它可能包含自己的libc和其他库所需代码的副本。如果从另一个使用libc的可执行文件加载DSO,则可能会产生问题。

如果您的DSO动态地与libc链接,那么DSO会在其动态依赖关系列表中添加所需的共享库,并在符号被加载之前保留未解析的符号。

让我们假设,我们正在处理后一种情况,因为它通常会发生什么。

加载DSO时,运行时链接程序递归加载所需的共享库,并为每个未解析的符号尝试确定其位置。例如,如果您的可执行文件已静态链接printf并且您的DSO想要使用它,则动态链接器会将DSO中的引用解析为指向可执行文件中的printf位置。如果可执行文件与libc动态链接,printf引用将指向libc.so中的代码。

如果在环境中设置LD_DEBUG = all并运行加载DSO(或任何动态链接的可执行文件)的应用程序,您可以查看正在进行的操作。您将看到动态链接器正在执行的操作。输出结果很冗长,但是应该让你大致了解幕后发生的事情。