如何在主程序中解析共享库的外部符号?

问题描述 投票:2回答:1

我一直在阅读很多关于共享库的加载时链接的语义,还有一件我难以理解的事情是主程序如何引用共享库中定义的函数?例如,假设我有这个代码

没有shared.是

int get(){
   return 0;
}

main.c中

  extern int get();
  int main(){
    int a = get();
  }

我理解,由于共享库不能对它们的放置位置做出任何断言,因此它们必须使用GOT和PLT来引用它们自己的函数和全局数据。但是,使用所述库的实际程序如何知道函数的加载位置,以便它可以引用它们?显然,链接器不知道,因为这些库的链接直到加载时才会发生。因此,我只能想到两种可以引用这些外部函数的方法。

  1. 链接器只是放置一些占位符,其中get(在上面的示例中)被调用,然后添加一些加载器所需的元数据,然后将占位符替换为函数的实际地址(就像使用共享库的方式一样) PIC之前的加载时重定位)但是这会导致显着的开销,并且是首先引入PIC的动机(我认为)
  2. 主程序也有自己的GOT和PLT,加载器也必须按照共享库的方式填充主程序的GOT(在全局变量的情况下加载时一次性加载,或者使用PLT以懒惰方式加载)对于功能)但这听起来像是重复的努力。

那么,这两个中的哪一个(如果有的话)是用于解析共享库的外部符号的方法?

c++ linux shared-libraries dynamic-linking relocation
1个回答
4
投票

主程序中的符号解析与共享库中的符号解析没有太大差别,可通过主程序的GOT和PLT表实现。你是正确的,这会在静态(ld)和动态(ld.so)链接器之间产生一定量的重复,并减慢程序启动速度,但另一方面允许在运行时增加灵活性(例如通过LD_PRELOAD插入符号)。

© www.soinside.com 2019 - 2024. All rights reserved.