首页
社区
课程
招聘
未解决 [求助]一个二进制关于动态链接的的问题
发表于: 2020-3-7 10:05 1775

未解决 [求助]一个二进制关于动态链接的的问题

2020-3-7 10:05
1775
关于装载时重定位,看到这样一句话
“动态链接模块被装载映射到虚拟空间后,指令部分是在多个进程之间共享的,[b]由于装载时重定位的方法需要修改指令[/b],所以没有办法做到同一份指令被多个进程共享,因为指令被重定位后对于每个进程来讲是不同的。”
共享文件的代码段,在物理内存被映射到每个进程的虚拟空间,也就是代码段是共享的,进程需要使用代码段的执行代码,只需要修改跳转地址,也就是装载时重定位。
黑体部分不太理解,修改指令,修改的是本进程的指令(可能有一些地址需要修改),而不是共享文件的指令,和共享文件不能被多个进程共享有什么关系?

查找了网上的一些说法,进程的指令被修改了(跳转地址),导致该进程指令,不能被其他进程使用?结合该问题的解决方法,使用plt,看起来像是这么理解的。但是这和共享文件有什么关系?共享文件完全还是可以使用的啊?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 3490
活跃值: (11148)
能力值: ( LV9,RANK:240 )
在线值:
发帖
回帖
粉丝
2
1. 你先把目光放在第一个加载test. so的进程上,这个时候test.so的代码段,必然要到物理内存上放一份,并且要从第一个进程的空闲虚拟空间,选一块跟这块物理空间建立映射;
2. 代码段中表示虚拟地址的那些地方,通常是test.so中的全局变量的虚拟地址,需要根据test.so加载的虚拟地址进行修改,那么对于目前来讲,要根据第一个进程中选的那块虚拟空间的位置进行修改;
3. 现在再考虑又有第二个进程要使用test. so,它可以按照上面的2步,再独立的加载一次,也就是让test. so再占一份物理空间,并且根据第二个进程中,选择的映射虚拟空间的位置,修改代码段,这样程序执行肯定也没问题,但test.so只是共享了代码逻辑,加载内存还是要大家各自一份;
4. 为了让test. so只需要一份物理内存,可以让从第二个进程选的虚拟空间,也映射到第一个进程加载时分配的物理内存,但这个时候就会出现一个矛盾,第一个进程和第二个进程,都需要按自己选的虚拟空间,对代码段进行修改,为了解决这个矛盾,就出现了got表(先别去想plt),got表其实就是集中存放需要修改内容的一个地方,代码段原本需要修改的地方可以理解成一级指针,那么现在就变成了二级指针,一级指针都集中放在got表里了,由于got表也在test. so文件里,跟代码段有固定的偏移,所以这些二级指针不需要到加载时才能知道,也就是说代码段里就没有需要修改的内容了,这样,往往很大一块代码段包含的少量一级指针,就集中到got表里了,从而每个进程需要独立拥有的,只有一个小got表,大块的代码段,就可以映射同一块的物理内存了;
5. plt本质上是为了实现函数的延迟重定位,并不是说函数的重定位就必须依赖plt,如果只需要达到内存共享的目标,仍然是有got表就够了。
要彻底搞明白这些,估计这几句回答还是不够,需要系统的去看些内核的虚拟地址管理,和一些系统的elf资料。
最后于 2020-3-8 08:53 被jmpcall编辑 ,原因: 手机打字的,没输入完不小心点到回帖按钮
2020-3-8 08:02
0
游客
登录 | 注册 方可回帖
返回
//