按需加载/卸载 ELF 部分?
对于一个相当模糊的用例,我想要一个(大型)静态链接的 Linux 可执行文件,由一小段控制代码和大段静态(只读)数据组成。为了节省内存,是否可以让加载器仅加载控制代码的部分,然后根据需要手动加载 RO 数据的部分,并在处理完成后再次卸载它们?
这可能吗?
(我想数据流(在文件系统级别)可以用来解决这个问题,但它们对我来说不可用(EXT3),而且分发会很棘手,因为数据流很容易丢失。)
For a rather obscure use case I'd like to have a (large) statically linked Linux executable made up of a small piece of control code and large pieces of static (read-only) data. Is it possible, to save memory, to get the loader to load only the sections for the control code, and then manually load the sections of RO data as they are needed, and unload them again once the processing is done?
Is this possible?
(I suppose data streams (on the filesystem level) could be used to solve this, but they aren't available to me (EXT3) and distribution would be tricky since data streams easily get lost.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,如果它是 ELF 文件的一部分,它将被映射。我不确定 ELF 的细节,但如果这是一个 PE 文件,您可以简单地将添加的数据标记到 PE 文件的末尾,超出 PE 结构。不属于 PE 结构一部分的数据不会映射到 Windows 中的内存。我怀疑 ELF 中也存在同样的情况。
No, if it's part of the ELF file, it will be mapped. I'm not sure of the particulars of ELF, but if this was a PE file, you could simply tag on your added data to the end of the PE file, beyond the PE structure. Data that isn't part of the PE structure doesn't get mapped to memory in windows. I suspect the same exists in ELF.
这(很可能)已经为您处理好了。
真正的答案当然取决于系统,但一般来说,现代操作系统(当然还有 Linux)对可执行文件使用需求分页,因此实际上不会为您未引用的 ELF 文件部分分配 RAM。
This is (very probably) already taken care of for you.
The real answer of course will be system-dependent, but in general, modern operating systems (and certainly Linux) use demand paging for executables, so no RAM will be actually allocated for sections of the ELF file you don't reference.
不要将 blob 链接到二进制文件中,而是将它们附加到二进制文件中。它们不会被映射,但您可以根据需要阅读或映射它们。
Instead of linking your blobs into the binary, append them to it. They won't be mapped, but you can read or map them as you need them.
有些答案有些误导,因为它们暗示整个二进制文件将被映射。不,那是错误的。并非所有内容都会被映射!
证明:
这是将被映射的唯一两个部分。为什么?因为这些是唯一具有 DT_LOAD 类型的:
您还会注意到虚拟地址与 ELF 文件中定义的相同。
实际上,您只能访问文件的前 40 KiB(0x8052000-0x8048000 = 40960 字节)。这对于 ELF 标头来说已经足够了,但您将无法访问 DWARF .debug 标头,更不用说字符串表 (.strtab) 了。
如果您想访问所有 ELF 部分,最简单的方法是映射整个文件。
Some answers are somewhat misleading as they imply that the whole binary will be mapped. No, that's wrong. Not everything will be mapped!
Proof:
That's the only two parts from the that will be mapped. Why? Because these are the only ones that have the type DT_LOAD:
You'll also notice that the virtual address is the same as defined in the ELF file.
In practice you'll only have access to the first 40 KiB (0x8052000-0x8048000 = 40960 Bytes) of the file. This is enough for the ELF headers but you won't be able to access say the DWARF .debug headers, let alone the string table (.strtab).
If you want access to all ELF sections, the easiest would be to map the whole file.