use*_*363 2 linux linux-kernel
我阅读了一些使用 -fPIC 参数编译共享库的文档,.so 的 .text 序列将在进程 fork 的动态链接阶段共享(例如,进程会将 .so 映射到相同的物理地址)
我对谁(内核或 ld.so )以及如何实现这一点感兴趣?也许我应该跟踪代码,但我不知道从哪里开始。
尽管如此,我还是尝试验证该声明。
我决定检查 libc.so 中的 printf 之类的函数地址,以便所有 c 程序都将链接。我得到了进程的printf虚拟地址,需要得到物理地址。尝试编写内核模块并将地址值传递给内核,然后调用 virt_to_phys。但它不起作用,因为 virt_to_phys 仅适用于 kmalloc 地址。
因此,进程页表查找可能是查找虚拟地址到物理地址的解决方案。有没有办法做页表查看?或者其他方式可以适应验证实验?
提前致谢!
动态加载器mmap(2)与 MAP_PRIVATE 和适当的权限一起使用。您可以通过从strace -e file,mmap. 例如:
strace -e file,mmap ls
Run Code Online (Sandbox Code Playgroud)
所有的魔法都来自于mmap(2)。mmap(2)在调用过程中创建映射,它们通常由文件或交换(匿名映射)支持。在文件支持的映射中,MAP_PRIVATE 意味着对内存的写入不会更新文件,并导致该页面从该点开始被交换支持(写入时复制)。
动态加载器从 ELF 的程序头中获取它需要的信息,您可以通过以下方式查看:
readelf -l libfoo.so
Run Code Online (Sandbox Code Playgroud)
从这些中,动态加载器确定将什么映射为代码、只读数据、数据和 bss(文件中大小为零的零填充段,内存中的非零大小,以及一个名称仅与 Lisp 的汽车和cdr)。
因此,实际上,代码和数据都是共享的,直到写入导致写入时复制。这就是为什么将常量数据标记为常量是一个潜在的重要空间优化(参见DSO howto)。
您可以在mmap(2)联机帮助页和文档/nommu-mmap.txt 中获得更多信息(MMU 情况下,no-MMU 用于嵌入式设备,如 ADSL 路由器和 Nintendo DS)。
| 归档时间: |
|
| 查看次数: |
4002 次 |
| 最近记录: |