关于elf文件load段上内存映射

(这里都是16进制数字)

这里ROUNDOWN是向下对齐,那么就是比如1434,1000对齐到1000,434对齐到0

这里ROUNUP是向上对齐,那么就是比如1434,1000对齐到2000,434对齐到1000

代码如上,

假设我们有两个load段,可以发现这俩load的偏移地址(关于可执行文件)是连在一起的,但是虚拟地址查了一个页表大小0x1000,我们过一遍代码

第一个load

offset=0

vaddr=10000+g,(g是一个偏移量,是吧这段load到虚拟内存闲的地方,然后它能被页表大小整除)

aligned_vaddr = 10000+g

filesz = 434+ 0;

memsz=434

那么mmap之后,就会在10000+g这个位置开始映射,然后距离文件开始位置为0的434字节映射

第二个load

offset=434

vaddr=11434+g,(g是一个偏移量,是吧这段load到虚拟内存闲的地方,然后它能被页表大小整除)

aligned_vaddr = 11000+g

filesz = 434+ 77c;

memsz=7b4+434

那么mmap之后,就会在11000+g这个位置开始映射,然后把距离文件开始位置为0的434+77c字节映射

 之后第二段还需要上.bss section

那么mmap之后,就会在11000+g+1000这个位置开始映射,然后把距离文件开始位置为0的remaining_bss字节映射,内容全部映射为0(匿名映射,映射为0)

那么最后的虚拟内存结构为(我们把g省去)

12000+remaining_bss-----

           .bss(全为0)

12000-----------------

11bb0------------------

               load2

11434------------------

                load1

11000------------------

10434------------------

               load1

10000 ------------------

最后发现是和程序头表所展示的虚拟内存是一样的

我们假设两个超过页表大小的段

                offset          vaddr         filesz

load1         0                10000        1434

load2        1434           12434        1434

第一个load

offset=0

vaddr=10000+g,(g是一个偏移量,是吧这段load到虚拟内存闲的地方,然后它能被页表大小整除)

aligned_vaddr = 10000+g

filesz = 1434;

那么mmap之后,就会在10000+g这个位置开始映射,然后距离文件开始位置为0的1434字节映射

第二个load

offset=1434

vaddr=12434+g,(g是一个偏移量,是吧这段load到虚拟内存闲的地方,然后它能被页表大小整除)

aligned_vaddr = 12000+g

filesz = 434+ 1434;

那么mmap之后,就会在12000+g这个位置开始映射,然后把距离文件开始位置为1000的434+1434字节映射

那么最后的虚拟内存结构为(我们把g省去)

12000+434+1434------------------

               load2

12434------------------

               一部分load1

12000------------------

11434------------------

               load1

10000 ------------------

最后发现是和程序头表所展示的虚拟内存是一样的

所以具体来说,就是关于offset,这部分就是之前段的总和

比如段a,b,c

a就是0

b就是size.a

c就是size.a+size.b

假设现在有俩段,大小分别是x和y

那么编译出来以后他们的虚拟地址会排布如下

x:10000

y:x.size%1000+10000+1000

也就是说,如果一个段多用了一个页表,下个段就把多出来的这部分记住,并且再开一个页表

这样当前一个段映射完以后,我们其实映射肯定是下一个页表(这时候y会被round)

那么多出来的这部分就是x.size%1000,那么就重新设置偏移位置

那么这个操作会往回走x.size%1000,因为y的offset就是包含了之前的所有的load大小

那么我们我们会发现,y round之后是11000,那么,偏移就是x.size%1000,也就是offset往回走,我们load y的时候多load了x某部分,这部分大小是x.size%1000,然后我们load大小也加了这个大小,最后结果就是再地址11000,load了大小为x.size%1000+y.size的文件

这样在虚拟地址上,我们load到正好是x.size%1000+10000+1000的位置开始是这个段,然后对齐页表的位置填充了一部分大小为x.size%1000的x段内容。

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值