链接、装载与库[7]动态链接

1.动态共享对象与动态链接库

  • 在Linux系统中,ELF动态链接文件被称为动态共享对象(DSO, Dynamic Shared Object),一般以 .so 为扩展名;
  • 在Windows中,动态链接文件被称为动态链接库DLL,以**.dll**为扩展名。

2.动态链接程序运行时地址空间分布

  • 共享对象.so的最终装载地址在编译时时不确定的,而是在装载时,装载器根据当前地址空间的空闲情况,动态分配一块足够大小的虚拟地址空间给相应的共享对象。
  • 可执行文件 往往是第一个被加载的文件,它可以选择一个固定空闲的地址,在Linux下它是0x08040000,在Windows下它是0x0040000。

3.4种寻址模式

1)模块内部的函数调用、跳转等;
2)模块内部的数据访问(如模块内部的全局变量、静态变量);
3)模块外部的函数调用、跳转等;
4)模块外部的数据访问(如其他模块中定义的全局变量)。

static int a;
extern int b;
extern void ext();

void bar()
{
  a = 1; //Type2, 模块内部的数据访问
  b = 2; //Type4, 模块外部的数据访问
}

void foo()
{
  bar();  //Type1, 模块内部的函数调用
  ext();  //Type3, 模块外部的函数调用
}
  • 模块内部的函数调用
    foo对bar的调用的指令实际上是一条相对地址调用指令
  • 模块间数据访问
    模块间的数据访问需要等到目标装载时才能决定。ELF的做法是在数据段里建立全局偏移表,它是指向模块外变量的指针数组

4.独立副本的Lib.so

  • 当Lib.so被两个进程(A和B)加载时,它的数据段部分在每个进程中都有独立的副本。因此假设A修改了Lib.so的全局变量G,B中的G不会受到影响。
  • 但是,由于两个线程共享同一个进程地址空间,线程A对G的修改对B是可见的。

5.延迟绑定实现

  • 在动态链接下,程序模块之间包含了大量的函数引用,所以在程序开始执行之前,动态链接会耗费不少时间用于解决模块之间的函数引用的符号查找以及重定位,这减慢了动态链接的性能。
  • ELF采用了延迟绑定(Lazy Binding),即当函数第一次被用到时才进行绑定,这大大加快了程序的启动速度,特别有利于一些有大量函数引用和大量模块的程序。

6.动态链接重定位相关数据结构

  • .rel.text: 动态链接中代码段的重定位表;
  • .rel.data: 动态链接中数据段的重定位表;

7.动态链接器的4个API

  • 操作系统通过动态链接器提供的4个API来实现链接库的装载:
  • void * dlopen(const char * filename, int flag );
    打开一个动态库,并将其加载到进程的地址空间。
    1)filename参数是加载动态库的路径;flag参数是函数符号的解析方式,常量RTLD_LAZY表示延迟绑定,RTLD_NOW表示当模块被加载时即完成所有的函数绑定工作;
    2)dlopen的返回值是被加载的模块的句柄。
  • void * dlsym(void * handle, char * symbol);
    如果dlsym()找到了相应的符号,则返回该符号的值;如果没有找到相应的符号,则返回NULL
  • dlerror()判断上一次调用是否成功
  • dlclose() 将一个已经加载的模块卸载
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《程序员的自我修养:链接,装载》是一本由林锐、郭晓东、郑蕾等人合著的计算机技术书籍,在该书中,作者从程序员的视角出发,对链接装载等概念进行了深入的阐述和解析。 在计算机编程中,链接是指将各个源文件中的代码模块组合成一个可执行的程序的过程。链接可以分为静态链接动态链接两种方式。静态链接是在编译时将所有代码模块合并成一个独立的可执行文件,而动态链接是在运行时根据需要加载相应的代码模块。 装载是指将一个程序从磁盘上加载到内存中准备执行的过程。在装载过程中,操作系统会为程序分配内存空间,并将程序中的各个模块加载到相应的内存地址上。装载过程中还包括解析模块之间的引用关系,以及进行地址重定位等操作。 是指一组可重用的代码模块,通过链接装载的方式被程序调用。可以分为静态和动态。静态是在编译时将代码链接到程序中,使程序与代码合并为一个可执行文件。动态则是在运行时通过动态链接的方式加载并调用。 《程序员的自我修养:链接,装载》对于理解链接装载的原理和机制具有极大的帮助。通过学习这些概念,程序员可以更好地优化代码结构和组织,提高程序的性能和可维护性。同时,了解链接装载的工作原理也对于进行调试和故障排除具有重要意义。 总之,链接装载是计算机编程中的重要概念,对于程序员来说掌握这些知识是非常必要的。《程序员的自我修养:链接,装载》这本书提供了深入浅出的解释和实例,对于想要学习和掌握这些知识的程序员来说是一本非常有价值的参考书籍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值