gpt4 book ai didi

memory-management - ELF 头和进程虚拟内存中的不同地址

转载 作者:行者123 更新时间:2023-12-04 07:42:06 25 4
gpt4 key购买 nike

我在linux下通过pmap看到进程镜像:

08048000       0       4       0 r-x--  [my program]

08049000 0 4 4 rw--- [my program]

上面三段分别是code、rodata和data段,都是按照PAGESIZE(4K)对齐的,但是当我输入objdump -h时,ELF头显示如下:
read-only code segment
Load off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00000448 memsz 0x00000448 flags r-x

read/write data segment
Load off 0x00000448 vaddr 0x08049448 paddr 0x08049448 align 2**12
filesz 0x000000e8 memsz 0x00000104 flag rw-

在ELF头中说,代码段和数据段分别从虚拟地址中的0x08048000,0x049448开始寻址,这与内存中的进程镜像不同。我知道代码/数据段应该分配给不同的PAGESIZE,这可以给它们不同的保护权限。但是,如果真正的虚拟与 Sprite 二进制不同,程序如何执行?

最佳答案

ELF 程序加载(以及一般从文件中进行内存映射)的方式是基于页面的。所以所涉及的地址、文件中的偏移量和大小都必须是页面大小的倍数。

但是,程序加载器足够聪明,可以通过将它们四舍五入到页面边界来处理不完全在页面边界上开始或结束的部分,映射比所需的更多。因此,将从文件中加载一些额外的数据以填充页面,但不应访问它,因此这无关紧要。

在您的示例中,代码段从偏移量 0x0 开始在地址 0x08048000 处加载,大小为 0x448。地址和偏移量是对齐的,因此只需要将大小四舍五入到整页。数据段从偏移 0x448 处加载到 0x08049448。这些不是对齐的,但是是兼容的——加载器向下舍入到一个页面的倍数(0x08049000 和 0x000)和该页面中的映射。请注意,这最终与文件中的代码段位于同一页,因此该页加载到两个不同的地址,一个是只读的,另一个是读写非共享的。所以代码和数据最终在过程镜像的两个位置都可见,但这并不重要——代码在 0x8048000..0x8048447 处结束,数据在 0x8049448..0x804954b 处结束,仅此而已事项。

关于memory-management - ELF 头和进程虚拟内存中的不同地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9756238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com