1. 显然,共享对象总是在.init_array之前存在差距.这只是一个大会吗?我找不到任何参考资料.

如果我的主程序加载太多SO,htop会显示虚拟内存空间使用率显着增加.这似乎很具有误导性,尽管我认为它对现实世界的影响为零,因为差距只是虚拟的,不会被引用并因此被翻页到物理内存中?

  1. 此外,大小列与实际磁盘空间不匹配.我的猜测是大小列中的总大小不考虑段/部分之间的填充.

gcc(Ubuntu 5.4.0- 6 ubuntu 1 ~16.04.12)5.4.0 20160609的最小示例,用于以下命令.在我try 过的其他系统中也是如此.

foo.c 中的内容

#include <stdio.h>


void foo(void)
{
    puts("Hello, I am a shared library");
}
gcc -c -Wall -Werror -fpic -g3 foo.c
gcc -shared -o libfoo.so foo.o

当判断SO文件时,我得到以下输出.

❯ size -A -d libfoo.so
libfoo.so  :
section               size      addr
.note.gnu.build-id      36       456
.gnu.hash               60       496
.dynsym                336       560
.dynstr                172       896
.gnu.version            28      1068
.gnu.version_r          32      1096
.rela.dyn              192      1128
.rela.plt               24      1320
.init                   26      1344
.plt                    32      1376
.plt.got                16      1408
.text                  275      1424
.fini                    9      1700
.rodata                 29      1709
.eh_frame_hdr           28      1740
.eh_frame              100      1768
.init_array              8   2100736
.fini_array              8   2100744
.jcr                     8   2100752
.dynamic               448   2100760
.got                    40   2101208
.got.plt                32   2101248
.data                    8   2101280
.bss                     8   2101288
.comment                53         0
.debug_aranges          48         0
.debug_info            145         0
.debug_abbrev           69         0
.debug_line            424         0
.debug_str           15511         0
.debug_macro          4020         0
Total                22225
❯ l -l libfoo.so
-rwxr-xr-x 1 root root 28936 Apr 17 18:48 libfoo.so*

推荐答案

@kakkoko为我指明了正确的方向.我发现this post人也在研究同样的问题.

The reason is that the linker would want to share the text section in shared libraries and not share the data section which comes afterward. So to ensure it's safe to share the text segment among multiple executions of the program, the linker would put the data section at the same offset in the next page.

文章质疑:"这并不能真正解释为什么所需的地址在下一页中具有相同的偏差,而不仅仅是下一页的开始.这可能就像最初是一件容易做的事情(最初)而逻辑却陷入困境一样简单."Ian Lance Taylor的解释:

我们同时跳到下一个虚拟页面是有原因的 offset. 不过,我在https://www.airs.com/blog/archives/45分钟内谈到了它 我想这不是很清楚. 通过使用相同的偏差,链接器可以 在文件中使用同一页面作为文本段的结尾和 数据段的开始. 该页面最终被映射两次: 一个只读且可执行文件作为文本段的一部分,一次 作为数据段的一部分读写. 这可以节省文件中的空间, 如果我们幸运的话,它会使文件缩短一页.

这是一个绝妙的技巧.如果要求我计算虚拟页面中的偏差,鉴于文本和数据在同一物理页面上彼此相邻,除非对齐填充,否则我可能会得到偏差公式.然而,我很难想出相反的方法:).

C++相关问答推荐

ARM上的Modulo Sim Aarch 64(NEON)

为指针 struct 创建宏

我可以动态分配具有空类型函数的矩阵吗?

如何通过Zephyr(Devicetree)在PR Pico上设置UTE 1?

GCC不警告隐式指针到整数转换'

如何创建由符号组成的垂直结果图形?

这是一个合法的C Strdup函数吗?

struct -未知大小

如何在C中打印包含扫描字符和整数的语句?

用gcc-msse 2编译的C程序包含AVX 1指令

S的这种管道实施有什么问题吗?

C11/C17标准允许编译器清除复合文字内存吗?

C语言中MPI发送接收字符串时出现的分段错误

C语言中的数字指针

从BIOS(8086)中读取刻度需要多少?

从整型转换为浮点型可能会改变其值.

如何使用calloc和snprintf

在C中交换字符串和数组的通用交换函数

中位数和众数不正确

如何在 C 中的 Postgres 函数的表中 for 循环