我正在使用readelf来找出二进制文件如此大的原因,但是我对输出感到困惑。或者我的二进制文件链接错误。现在二进制是大约380MB,如果我这样做:
readelf-W-s二进制| awk'NR>3{sum+=$3}结束{print sum}'
我得到236221726字节。看起来很低,但也许我缺少静态符号或其他什么。但如果我这样做了:
readelf-W-s二进制|排序-n-r-k 3 |更少
我看到这个:
172766:000000000CF8D96099993 FUNC全局默认值10 symbolA
147338:000000000 cf8d960 99993 FUNC全局默认值10 symbolB
132791:000000000CF8D96099993 FUNC全局默认值10 symbolA
107363:000000000 cf8d960 99993 FUNC全局默认值10 symbolB
其中symbolA和symbolB只有1个字符不同,并且要求相同的东西。
所以,我的问题是:
1)如果这些东西有相同的地址,我的二进制文件中是否有四个副本?
2)如果没有四个副本,这些是别名,readelf不应该报告吗?
3)如果是四份,如何以及为什么?我想我在做一件不好的事情。
4)如果没有四个副本,那么readelf的总大小比二进制文件的实际大小要小-为什么?
编辑:添加更多信息。。。上述readelf输出来自完全链接的二进制文件。仅仅看一下包含symbolA/symbolB的.o,readelf仍然报告同一地址的每个symbolA和symbolB的一个副本。
但是如果我objdump-d.o文件,我只看到symbolA的assembly。
那么-objdump或readelf是“错误”的吗?
最佳答案
如果将函数定义放在头中,然后将此头包含在不同的源文件中,则将为每个包含生成不同的函数(好吧,除非它在特定源文件中的任何位置都是内联的)。不看你的消息来源很难说出来,但事实可能就是这样。
考虑在单独的源文件中移动大型不可内联函数,在相应的头文件中只保留声明。这也许能达到目的。