ELF加载器如何映射小于页面大小的部分?
mmap 手册页指出“文件以页面大小的倍数映射。”,在我的系统上为 4096 字节 (0x1000)。然而 ELF 文件可以有小于 0x1000 的部分,例如:
[Sections]
nth paddr size vaddr vsize perm name
―――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000000 0x0 0x00000000 0x0 ----
1 0x00001000 0xb93 0x00401000 0xb93 -r-x .text
2 0x00002000 0x660 0x00402000 0x660 -r-- .rodata
3 0x00002660 0x304 0x00402660 0x304 -r-- .eh_frame
4 0x00003000 0xe6 0x00404000 0xe6 -rw- .data
5 0x000030e6 0x0 0x00404100 0x100 -rw- .bss
6 0x000030e6 0x2e 0x00000000 0x2e ---- .shstrtab
ELF 如何加载和映射它们?它不能天真地向上舍入到 0x1000,因为那样下一部分就会失败。它是否以某种方式检测到这一点并将连续页面分组在一起?如果他们有不同的权限怎么办?
The mmap man page states "A file is mapped in multiples of the page size.", which on my system is 4096 bytes (0x1000). Yet ELF files can have sections smaller than 0x1000, for example:
[Sections]
nth paddr size vaddr vsize perm name
―――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000000 0x0 0x00000000 0x0 ----
1 0x00001000 0xb93 0x00401000 0xb93 -r-x .text
2 0x00002000 0x660 0x00402000 0x660 -r-- .rodata
3 0x00002660 0x304 0x00402660 0x304 -r-- .eh_frame
4 0x00003000 0xe6 0x00404000 0xe6 -rw- .data
5 0x000030e6 0x0 0x00404100 0x100 -rw- .bss
6 0x000030e6 0x2e 0x00000000 0x2e ---- .shstrtab
How does ELF load and mmap them? It can't naively round up to 0x1000, because then the next section would fail. Does it somehow detect this and group the contiguous pages together? What if they have different permissions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ELF 加载器不会查看或关心任何部分。事实上,节头可以被完全剥离,并且可执行文件将继续正常工作。节仅在(静态)链接时使用。
加载器关心的是段。您可以使用 readelf -Wl a.out 来查看段(以及段到段的映射)。
是的:段的页长度可以不均匀。加载器并不关心——它只是执行
mmap()
(内核将映射四舍五入到整个页面大小)。另请参阅此部分相关的答案。
The ELF loader doesn't look at, or cares about any sections. In fact section headers can be fully stripped, and the executable will continue to work just fine. Sections are used only at (static) link time.
What the loader does care about are segments. You can see segments (and mapping of sections to segments) with
readelf -Wl a.out
.And yes: segments can have non-even page length. The loader doesn't care -- it simply performs
mmap()
(the kernel rounds the mapping up to whole page size).See also this partially relevant answer.
它可能只会为您的请求提供一个完整的页面,但正如您所说,允许的内存量只是您请求的内存量。这样做的目的是为了不与任意请求的可能性发生冲突,并且是独立于系统的。如果您调整内存量的大小,请考虑您所需的确切内存量。
It will probably just dedicate a full page to your request, but as you stated, the amount of memory conceeded is only the amount you requested. This is made to neither conflict with the possibility of arbrtrary requests, and to be system independent. In case you resize the amount of memory, to take into account the exact amount of memory you have asked for.