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

C 在动态加载库(DSO)中导入符号,c,dynamic,dll,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"); } #包括 int foo(无效){ printf(“你好,世界!\n”); } 动态链接器如何知道print

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

例如: 假设我用下面的代码将z.c文件编译成SO

#include <stdio.h>

int foo(void){
  printf("hello world!\n");
}
#包括
int foo(无效){
printf(“你好,世界!\n”);
}

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

通常,假设静态库使用与共享库兼容的ABI(并非所有平台都是如此),则符号解析将委托给动态链接器

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

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

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

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

如果在环境中设置LD_DEBUG=all并运行加载DSO(或任何动态链接的可执行文件)的应用程序,您可以看到发生了什么。您将看到动态链接器正在做什么。输出是冗长的,但应该让您大致了解引擎盖下发生了什么