首页 > 其他分享 >动态链接的实现

动态链接的实现

时间:2022-12-28 10:12:18浏览次数:37  
标签:符号表 全局 实现 装载 对象 共享 动态 链接

  1. 启动链接器
  2. 装载所有需要装载的对象
  3. 重定位和初始化

 动态链接器的自举:

  动态链接器本身也是一个共享对象。动态链接器的特殊性在于它不可以依赖其他共享对象,它所依赖的全局和静态变量的重定位的工作由自己完成。当操作系统将控制权交给动态链接器,它就开始了自举的过程。

装载共享对象:

完成基本自举以后,动态链接器将可执行文件和链接器本身的符号表都合并到一个符号表当中,我们可以称它为全局符号表( Global Symbol Table)。然后链接器开始寻找可执行文件所依赖的共享对象,我们前面提到过“ .dynamic"段中,有一种类型的入口是DT_ NEEDED,它所指出的是该可执行文件(或共享对象)所依赖的共享对象。由此,链接器可以列出可执行文件所需要的所有共享对象,并将这些共享对象的名字放入到一个装载集合中。然后链接器开始从集合里取-个所需要的共享对象的名字,找到相应的文件后打开该文件,读取相应的ELF文件头和“.dynamic"段,然后将它相应的代码段和数据段映射到进程空间中。如果这个ELF共享对象还依赖于其他共享对象,那么将所依赖的共享对象的名字放到装载集合中。如此循环直到所有依赖的共享对象都被装载进来为止,当然链接器可以有不同的装载顺序,如果我们把依赖关系看作一个图的话,那么这个装载过程就是一个图的遍历过程,链接器可能会使用深度优先或者广度优先或者其他的顺序来遍历整个图,这取决于链接器,比较常见的算法一般都是广度优先的。当一个新的共享对象被装载进来的时候,它的符号表会被合并到全局符号表中,所以当所有的共享对象都被装载进来的时候,全局符号表里面将包含进程中所有的动态链接所需要的符号。

符号的优先级:两个模块定义了同一个符号,装载进来的时候,全局符号表中,后来的直接被忽略。这种现象被称为全局符号介入。全局符号介入与地址无关代码

前面介绍地址无关代码时,对于第-类模块内部调用或跳转的处理时,我们简单地将其当作是相对地址调用/跳转。但实际上这个问题比想象中要复杂,结合全局符号介入,关于调用方式的分类的解释会更加清楚。还是拿前面“pic.c"的例子来看,由于可能存在全局符号介入的问题,foo 函数对于bar的调用不能够采用第一类模块内部调用的方法,因为一旦bar函数由于全局符号介入被其他模块中的同名函数覆盖,那么foo如果采用相对地址调用的话,那个相对地址部分就需要重定位,这又与共享对象的地址无关性矛盾。所以对于bar()函数的调用,编译器只能采用第三种,即当作模块外部符号处理,bar()函数被覆盖,动态链接器只需要重定位“.got.plt", 不影响共享对象的代码段。

 

重定位和初始化

当上面的步骤完成之后,链接器开始重新遍历可执行文件和每个共享对象的重定位表,将它们的GOT/PLT中的每个需要重定位的位置进行修正。因为此时动态链接器已经拥有了进程的全局符号表,这个修正过程跟地址重定位的原理基本相同。重定位完成之后,如果某个共享对象有“.init"段,那么动态链接器会执行“.init"段中的代码,用以实现共享对象特有的初始化过程,比如最常见的,共享对象中的C++的全局/静态对象的构造就需要通过“.init"来初始化。相应地,共享对象中还可能有“.finit" 段,当进程退出时会执行“.finit"段中的代码,可以用来实现类似C++全局对象析构之类的操作。

标签:符号表,全局,实现,装载,对象,共享,动态,链接
From: https://www.cnblogs.com/wuyun--wy/p/17007458.html

相关文章

  • 动态链接性能优化及相关结构
    动态链接确实有很多优势,比静态链接要灵活的多,但是它是以牺牲一部分性能为代价的。 性能优化:延迟绑定(PLT):当函数第一次调用时,才进行绑定(符号查找,重定位等)。当我们调用......
  • 实现动态域名解析DDNS
    https://help.aliyun.com/document_detail/431629.html?spm=5176.smartservice_service_robot_chat_new.0.0.26bef625nZZyid 实现动态域名解析DDNS更新时间:2022-09-2......
  • 动态链接后记
    Linux动态链接器本身是一个共享对象,还是一个可执行程序。支持动态链接的系统往往都支持一种更加灵活的模块加载方式:运行时加载。也就是让程序自己在运行时控制加载指定的......
  • vue 实现通过字符串关键字符动态渲染 input 输入框
    vue实现通过字符串关键字符动态渲染input输入框今天做一个简单的demo,就是有一个字符串,字符串里面有标识符,前端检测到标识符之后,需要将这个标识符转换成一个input输入框......
  • Perl实现的命令行小工具sshfind:通过主机名称关键字搜索和筛选~/.ssh/config主机配置项
    作用读取SSH客户端配置文件~/.ssh/config,根据主机名称筛选对应的主机相关配置项,适用于~/.ssh/config主机信息过多,不便于查找的情况,如本人该文件配置了500+主机;使用方法:......
  • Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程as
    普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态。而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在Python3......
  • asp实现301跳转的方法
    301重定向大家都知道它的好处了,可是,我们如何知道它是301重定向还是302重定向呢?真假301重定向检测方法 先把302重定向的asp代码贴出来:<%ifRequest.ServerVariables("SERV......
  • .NetCore中EFCore查询参数不固定,动态创建表达式树的方法
    第3方开源的有:​​https://github.com/davideicardi/DynamicExpresso​​​​https://github.com/microsoft/RulesEngine​​​​https://github.com/zzzprojects/System.Li......
  • 实现小程序onShow第一次页面加载不执行
    实现小程序onShow第一次页面加载不执行1.业务场景在做小程序实际的业务中,是否有过在当前列表页点击某个入口,跳转到修改页面,在跳回当前页面并重新刷新数据的需求?2.分析......
  • Redis 如何实现库存扣减操作和防止被超卖?
    本文已经收录到Github仓库,该仓库包含计算机基础、Java核心知识点、多线程、JVM、常见框架、分布式、微服务、设计模式、架构等核心知识点,欢迎star~Github地址:​​https://gi......