为什么GCC在共享对象中.init_data的虚拟内存地址前加一个空格

问题描述 投票:0回答:1
  1. 显然,共享对象中的
    .init_array
    之前总是有一个间隙。这只是一个约定吗?我找不到任何相关参考。

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

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

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609 的最小示例,用于以下命令。我尝试过的其他系统也是如此。

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*
c++ c gcc
1个回答
0
投票

@kakkoko 为我指明了正确的方向。我发现这篇文章也探讨了同样的问题。

原因是链接器希望共享共享库中的文本部分,而不是共享后面的数据部分。因此,为了“防止文本段在程序的多次执行之间共享”,链接器会将数据段放在下一页中的相同偏移处。

“这并不能真正解释为什么所需的地址与下一页中的偏移量相同,而不仅仅是下一页的开头。它可能就像最初是容易做的事情一样简单(最初)并且逻辑被卡住了。”我想一个好处是我们可以简单地从总虚拟内存使用量中减去链接器认为可能的最大页面大小,然后查看程序的其余部分使用了多少。 伊恩·兰斯·泰勒肯定知道。

© www.soinside.com 2019 - 2024. All rights reserved.