0

我正在使用 readelf 来弄清楚为什么二进制文件这么大,但我对输出感到困惑。或者我的二进制文件链接非常错误。现在二进制文件大约是 380MB,如果我这样做:

readelf -W -s 二进制文件 | awk 'NR > 3 { sum += $3 } END { 打印总和 }'

我得到 236221726 字节。似乎很低,但也许我缺少静态符号或没有。但如果我这样做:

readelf -W -s 二进制文件 | 排序 -n -r -k 3 | 较少的

我看到这个:

172766:000000000cf8d960 99993 FUNC 全局默认值 10 符号A

147338: 000000000cf8d960 99993 FUNC 全局默认值 10 符号 B

132791: 000000000cf8d960 99993 FUNC 全局默认值 10 符号A

107363: 000000000cf8d960 99993 FUNC 全局默认值 10 符号 B

其中 symbolA 和 symbolB 仅 1 个字符不同,并且对同一事物进行分解。

所以,我的问题:1)如果这些东西有相同的地址,我的二进制文件中实际上有四个副本吗?2)如果没有四个副本,并且这些是别名,那么 readelf 不应该报告吗?3)如果是四个副本,如何以及为什么?我假设我在做一些不好的链接方式。4)如果没有四个副本,那么来自 readelf 的总大小远低于二进制文件的实际大小 - 为什么?

编辑:添加更多信息...上面的 readelf 输出来自完全链接的二进制文件。仅查看包含 symbolA/symbolB 的 .o,readelf 仍然在同一地址报告每个 symbolA 和 symbolB 的 1 个副本。

但是如果我 objdump -d .o 文件,我只会看到 symbolA 的程序集。

那么 - objdump 或 readelf 是“错误的”吗?

4

1 回答 1

0

如果将函数定义放在头文件中,然后将此头文件包含在不同的源文件中,则会为每个包含生成不同的函数(好吧,除非它在特定源文件中的任何地方都内联)。如果不查看您的消息来源,很难判断,但情况可能就是这样。

考虑在单独的源文件中移动大的不可内联函数,只在相应的头文件中留下声明。这可能会奏效。

于 2017-05-24T20:21:10.297 回答