我已经阅读了很多有关共享库的加载时链接的语义的知识,而我很难理解的一件事是,主程序如何引用共享库中定义的函数?例如,说我有这段代码
myShared.sh
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
插入符号)。
关于c++ - 如何在主程序中解析共享库的外部符号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54785183/