我一直在阅读很多关于共享库的加载时链接的语义,还有一件我难以理解的事情是主程序如何引用共享库中定义的函数?例如,假设我有这个代码
没有shared.是
int get(){
return 0;
}
main.c中
extern int get();
int main(){
int a = get();
}
我理解,由于共享库不能对它们的放置位置做出任何断言,因此它们必须使用GOT和PLT来引用它们自己的函数和全局数据。但是,使用所述库的实际程序如何知道函数的加载位置,以便它可以引用它们?显然,链接器不知道,因为这些库的链接直到加载时才会发生。因此,我只能想到两种可以引用这些外部函数的方法。
get
(在上面的示例中)被调用,然后添加一些加载器所需的元数据,然后将占位符替换为函数的实际地址(就像使用共享库的方式一样) PIC之前的加载时重定位)但是这会导致显着的开销,并且是首先引入PIC的动机(我认为)那么,这两个中的哪一个(如果有的话)是用于解析共享库的外部符号的方法?
主程序中的符号解析与共享库中的符号解析没有太大差别,可通过主程序的GOT和PLT表实现。你是正确的,这会在静态(ld
)和动态(ld.so
)链接器之间产生一定量的重复,并减慢程序启动速度,但另一方面允许在运行时增加灵活性(例如通过LD_PRELOAD
插入符号)。