动态链接的步骤与实现

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

动态链接器本身也是一个共享对象,但事实上其本身具有一些特殊性。动态链接器要能完成对普通共享对象的链接与装载,那对链接器本身,其重定位工作又该由谁来完成?

1.对动态链接器的要求:

  为了解决上述的问题,对动态链接器有以下两个要求:


1.动态链接器本身不可以依赖于其他共享对象

2.动态链接器本身所需要的全局与静态变量的重定位工作要由其自身完成

2.满足要求的办法:

对于动态链接器的第一个要求我们可以认为的控制,在编写动态链接器时不适用任何系统库,运行库;但对第二个要求,动态链接器必须在启动时有一段非常精巧的代码可以完成重定位工作同时有不能用到全局和静态变量。这种有限制的启动代码称为自举

3.Linux下动态链接器工作的全过程:

内核在装载完ELF可执行文件后返回到用户空间,并将控制权交给程序的入口,对静态链接的可执行文件而言,程序的入口就是ELF文件头里面指定的入口;对动态链接的可执行文件而言,内核会分析它的动态链接器地址(在.interp段中指定),将动态链接器映射至进程地址空间,然后将控制权交给动态链接器

动态链接器的入口地址即是自举代码的入口地址,自举代码首先会找到自己的GOT,而GOT的第一个入口保存的是".dynamic"段的偏移地址,由此找到该段,通过“.dynamic”段可以获得动态链接器本身的重定位表和符号表等,从而得到动态链接器本身的重定位入口,完成自身的重定位。从这一步开始,动态链接器才可以使用自己的全局变量和静态变量。

完成基本自举后,动态链接器将可执行文件和链接器本身的符号表都合并到一个全局符号表中,然后链接器在“.dynamic”段中找到该可执行文件依赖的共享对象,链接器将这些共享对象的名字加入到一个装载集合中,然后链接器从这个集合中取一个共享对象的名字,找到相应的文件后打开该文件,读取相应的ELF头与其“.dynamic”段,然后将相应的代码段与数据段映射到进程空间中,如果这个共享对象还依赖别的对象,则继续加入装载集合,循环直到所有相关共享对象均加入到进程空间,通常,采用广度优先加载共享对象。

当一个新的共享对象被装载进来时,其符号表会被合并到全局符号表中,所以当所有的共享对象都被装载进来后,全局符号表中将包含进程中所有动态链接需要的符号。

当所有共享对象加载完毕之后,动态链接器将控制权交回给ELF头中指定的程序入口地址

4.符号之间的优先性

全局符号介入(Global Symbol Interpose):一个共享对象中的全局符号被另一个共享对象中的同名全局符号覆盖的现象

Linux对全局符号介入的处理:当一个符号需要被加入全局符号表时,如果相同的符号名已经存在,则后加入的符号将被忽略。

这种处理方式将会导致后加入的函数被忽略不得以执行,当两个函数功能不相同时,可能会在莫名其妙的地方报错。

5.动态链接器的性质

动态链接器是一个特殊的共享对象,它不仅是共享对象,还是可执行文件。Linux的内核在执行execve()时不关心目标ELF文件是否可执行,它的工作是按照程序头表里的描述对文件进行装载然后将控制权转给ELF的入口地址。而共享对象其实也是ELF文件,也有跟可执行文件一样的ELF文件头,因此,动态链接器本身就可以作为可执行文件运行。(如果没有“.interp”就是动态链接器,否则是动态链接可执行文件)

动态链接器本身是静态链接的,且不能依赖别的共享对象。

动态链接器本身可以是PIC的也可以不是,但若是PIC的会简单些。否则,动态链接器的代码段将无法共享,浪费内存。

动态链接器可被当做可执行文件,且其装载地址是0x00000000,这是一个无效装载地址,作为一个共享库,内核在装载它的时候会为其选择合适的装载地址。

6.显示运行时链接

显示运行时链接(Explicit Run-time Linking),也叫运行时加载:让程序自己在运行时控制 加载指定的模块,并可以在不需要该模块时将其卸载。

这种可以由程序控制是否装载的共享对象称为动态装载库(Dynamic Loading Library.DLL,与动态链接库不同)。这种动态库与普通的共享对象相同,区别在于程序开发者的使用方式不同:

1.普通共享对象:由动态链接器在程序启动之前负责装载与链接,这些步骤由动态链接器完成,对程序员而言是透明的。

2.动态库:这种共享对象的装载与卸载都是由程序员在程序中控制的

Linux动态链接实现原理及编程实例 动态链接的主要任务是在程序加载时查找和加载所需的共享,并将其链接到程序代码中。当一个程序需要调用某个函数时,动态链接会在预定义的共享搜索路径中查找相应的文件,并将其加载到内存中。在Linux系统中,动态链接负责查找和加载所需的共享,并将其链接到程序代码中。在这个示例中,动态链接在程序加载时自动查找并加载了所需的printf函数的实现动态链接的原理及实现方式在Linux系统中被广泛应用,本文将详细介绍动态链接的原理,并提供一个简单的编程示例来演示其用法。 阅读详情

相关推荐

Linux动态链接实现步骤详解

Linux下,动态链接主要通过共享对象文件(Shared Object)来实现。共享对象文件是一种特殊的二进制文件,它包含了可被多个程序共享的代码和数据。动态链接是一种在程序运行时将所需的文件加载到内存并进行链接的机制。Linux操作系统提供了强大的动态链接功能,使得程序的开发和维护更加方便和灵活。本文将详细讲解Linux动态链接实现步骤,并提供相应的源代码示例。动态链接的好处在于可以实现代码的重用,减小可执行文件的大小,并方便进行文件的更新和维护。将上述代码保存为shared.c。

ByteWhizX的博客 167

动态链接(三) 动态链接步骤实现

大体步骤动态链接的自举(.dynamic段有关)装载共享对象(涉及全局符号表,符号优先级等) 重定位初始化1>gcc -Xlinker -rpath ./表示链接在当前路径寻找共享对象 2>当共享装载到进程的地址空间,则同时它们中的符号都会被并入到全局符号表 3>完

carltraveler的专栏 1636

程序员的自我修养(十一) -- 动态链接步骤实现

动态链接步骤 启动动态链接本身 装载所有需要的共享对象 重定位和初始化 动态链接自举 动态链接本身也是一个共享对象,但是它有一些特殊性: 动态链接本身不可以依赖其他任何共享对象 动态链接本身所需要的全局和静态变量的重定位工作由它本身完成==》这一点就用到了自举 自举是什么? 它是一种具有一定限制条件的启动代码 动态链接的入口地址即自举代码的入口,当操作系统将进程控制权交给动态...

qq_36308972的博客 380

动态链接实现

动态链接和静态链接不同,为了节省空间,在链接的时候,动态只是将自己的符号表可执行文件绑定在了一起生成了一个.o的可执行文件,真正的链接,实际上发生在程序运行实施装载的时候。 装载的时候,操作系统将动态链接加载完后(动态链接也是一个共享对象),就将控制权交给动态链接的入口地址。当动态链接得到控制权后,它就开始将自身进行初始化,然后根据当前的环境参数,对可执行文件进行动态

我的大学 660

Linux动态链接步骤实现详解

转自:Linux动态链接步骤实现详解_Linux编程_Linux公社-Linux系统门户网站 1. 动态链接的自举 我们知道动态链接本身也是一个共享对象,但是事实上它有一些特殊性。对于普通共享对象文件来说,它的重定位工作由动态链接来完成。他也可以依赖其他共享对象,其中的被依赖共享对象由动态链接负责链接和装载。可是对于动态链接来说,它的重定位工作由谁来完成?它是否可以依赖于其他共享对象? 这是一个“鸡生蛋,蛋生鸡”的问题,为了解决这种无休止的循环,动态链接这个“鸡” 必须有些特殊性。首

wmzjzwlzs的专栏 753

Linux动态链接3:动态链接实现步骤

最近打算抽空学习张绍文老师的《Android开发高手课》。想要彻底理解本地监控APP内存的框架的实现原理。发现理解起来都没有那么容易,在阅读代码的过程中,发现C++、linux、native hook、framework等方面的功底均有所不足。张绍文老师说过:“看再多的文章,不去思考文章所讲的内容和意图也是没用的;思考再多,不去动手真正实践也是没用的。“把进阶的各个主题由点到线串联起来,但这背后必然少不了一些基础的、底层的知识进行支撑”。这里就把空缺的知识进行补足。

Shujie 150

C++编写DLL动态链接步骤实现方法

原文:http://www.jb51.net/article/90111.htm 本文实例讲述了C++编写DLL动态链接步骤实现方法。分享给大家供大家参考,具体如下: 在写C++程序时,时常需要将一个class写成DLL,供客户端程序调用。这样的DLL可以导出整个class,也可以导出这个class的某个方法。 一、导出整个class 方法很简单,只需要在类的头文件中...

235

《程序员的自我修养》学习笔记(九)————动态链接(4):动态链接步骤实现

动态链接步骤基本上分为3步:先是启动动态链接本身,然后装载所有需要的共享对象,最后是重定位和初始化。 1.动态链接自举 动态链接本身也是一个共享对象,但是事实上它有一些特殊性。对于普通共享对象文件来说,它的重定位工作由动态链接来完成;它也可以依赖于其它共享对象,其中的被依赖的共享对象由动态链接负责链接和装载动态链接的特殊性:首先是,动态链接本...

yangguoyu8023的博客 374

android的APP调用C语言的动态链接实现步骤

1.新建一个类test,通过 System.loadLibrary()的方式将so加载进去,注意不要带有lib 和 so 比如libhello.so,为System.loadLibrary(hello),如下文所示,JAVA 调用addtest,返回的Addtest为jni接口 public static int addtest(int test ){ return Addtest(tes

chaoyuebaihu的专栏 2948

读书-程序员的自我修养-链接、封装(20:第七章:动态链接(4)动态链接步骤实现

读书-程序员的自我修养-链接、封装(20:第七章:动态链接(4)动态链接步骤实现)1. 动态连接自举1.1 动态链接本身也是一个共享对象1.2 动态连接特点:不依赖,自己玩,不调用1.3 自举:具有一定限制条件的启动代码往往被称作自举2. 装载共享对象2.1 全局符号表2.2 装载过程步骤2.3 装载顺序:广度优先和深度优先2.4 符号的优先级2.4.1 问题:多个共享对象定义同一个符号怎么处理?2.4.2 例子说明2.4.3 全局符号介入:符号覆盖2.4.4 linux处理规则:后面的同名符

哈尼的博客 350

怎么用c语言编写dll动态,C++编写DLL动态链接步骤实现方法

本文实例讲述了C++编写DLL动态链接步骤实现方法。分享给大家供大家参考,具体如下:在写C++程序时,时常需要将一个class写成DLL,供客户端程序调用。这样的DLL可以导出整个class,也可以导出这个class的某个方法。一、导出整个class方法很简单,只需要在类的头文件中class和类名之间加上_declspec(dllexport),同时在另外一份提供给客户端调用程序使用的类的头...

weixin_39546520的博客 903

《程序员的自我修养——链接、装载》读书笔记—— 7.6 动态链接步骤实现

简述 动态链接可以分为以下几个步骤动态链接的自举 装载共享对象 重定位和初始化

weixin_43512663的博客 531

动态链接介绍

模块间的访问比模块内部稍微麻烦一点,因为模块间的数据访问目标地址要等到装载时才决定,我们前面提到要使得代码地址无关,基本的思想就是把跟地址相关的部分放到数据段里面,很明显,这些其他模块的全局变量的地址是跟模块装载地址有关的。如此循环直到所有依赖的共享对象都被装载进来为止,当然链接可以有不同的装载顺序,如果我们把依赖关系看作一个图的话,那么这个装载过程就是一个图的遍历过程,链接可能会使用深度优先或者广度优先或者其他的顺序来遍历整个图,这取决于链接,比较常见的算法一般都是广度优先的。

biu801的博客 1332

动态链接(二):使用Rust实现一个动态链接

介绍动态链接的功能,并提供了一个动态链接实现

justdoyaya的博客 1588

动态链接

动态链接 为什么需要动态链接 静态链接使得不同的程序开发者和部门能够相对独立的开发和测试自己的程序模块,从某种意义上来讲大大促进了程序开发的效率,原先现在程序规模也随之扩大。 但静态链接的缺点也暴露出来:浪费内存、磁盘空间、模块更新困难。 内存磁盘空间 静态链接在计算机早期还是比较流行的,但是到了后面,其缺点也非常明显。比如浪费内存和磁盘空间,更新模块困难等。 举个例子,每个程序内部除了都保留了...

Coder_py的博客 4409

Firebase 动态链接

1 简介 通过动态链接,您的用户可以在他们打开您的链接的平台上获得最佳体验。如果用户在 iOS 或 Android 上打开一个动态链接,则可以直接转到您的原生应用中的链接内容。如果用户在桌面浏览中打开相同的动态链接,则可以转到您网站上的同等内容。 此外,无论应用是否已安装,动态链接都可以工作:如果用户在 iOS 或 Android 上打开一个动态链接,但还没有安装您的应用,则可以提示该用户安装您...

有趣的难受 1789
上一篇: 红黑树的思想
下一篇: 显示运行时链接的函数与例子,dlopen,dlsym,dlerror,dlclose
Virtual_Func
博客等级 码龄11年 38粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值